2024年10月12日 星期六

[8051]設計簡單的通訊協定以POS機串接的通訊為例

參考教材:單晶片微處理機實習,黃嘉輝,台科大出版

前一篇文章:偵測通訊狀態,顯示連線/斷線和秒數

POS機串接的通訊格式:通訊規格

程式碼:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <regx51.h>

#define STX 0x02
#define ETX 0x03
unsigned char SendBuf[]="51015100peanut10";
unsigned char ReceiveBuf[16];
int receive_cnt=0;
unsigned char buf;
int count=1000;									//1秒=1000*1ms
int on_line_sec=0;							//連線秒數
int on_line_status=0;						//onlne or offline
int is_receive=0;								//是否有接收

// 使用函數的設定區
extern void LCD_Init(void);
extern void LCD_Out(unsigned char x, unsigned char y, unsigned char *text);
extern void LCD_Out_Cp(unsigned char *text);
extern void LCD_Chr(unsigned char x, unsigned char y, unsigned char c);
extern void LCD_Chr_Cp(unsigned char c);
extern void LCD_Cmd(unsigned char cmd);
extern void LCD_GotoXY(unsigned char x, unsigned char y);

// 使用命令的設定區
extern unsigned char LCD_CURSOR_ON;
extern unsigned char LCD_CURSOR_OFF;
extern unsigned char LCD_CLEAR;

void init_UART(unsigned int baudrate)
{
		SCON=0x52;
		TMOD=0x20;
		TH1=256-((11059200/384)/baudrate);
		TL1=TH1;
		TR1=1;
}

void T0_int(void) interrupt 1
{
	TL0=(8192-1000)%32;						//重設設定值
	TH0=(8192-1000)/32;
	if(count==0)					//連線已經有1秒了嗎?
	{
		if(on_line_status)
			{
				on_line_sec++;
				on_line_sec%=100;
				LCD_Chr(2,16, on_line_sec%10+0x30);    //將接收到的資料送往顯示
				LCD_Chr(2,15, on_line_sec/10+0x30);    //將接收到的資料送往顯示
			}
		if(!is_receive)
			{
				LCD_Cmd(LCD_CLEAR);
				LCD_Out(2,1,"offline");
				on_line_status=0;
				on_line_sec=0;
			}
		is_receive=0;	 
		count=1000;									//1秒count
	}
	else
		count--;										//count每1ms減1
}

void UART_int(void) interrupt 4		//串列中斷函式	
{
	if(RI==1)												//是不為接收中斷?
	{
		RI=0;													//完成後清除RI
		buf=SBUF;											//將接到的資料給buf
		if(buf == 0x02)
			receive_cnt=0;
		else if (buf == 0x03)
			LCD_Out(1,1,ReceiveBuf);
		else 
			ReceiveBuf[receive_cnt++]=buf;
		is_receive=1;
		if(!on_line_status){
			on_line_sec=0;
			on_line_status=1;
			LCD_Out(2,1,"online ");
			count=1000;	
		}
	}
	else
		TI=0;													//如果是傳送中斷,則清除TI,下次才方再傳送
}

void Delay_ms(unsigned int count) 						//延遲count*1ms函式
{
				unsigned int i,j;
				for(i=0;i<count;i++)
								for(j=0;j<123;j++);
}

void main(void)
{
			unsigned int i;
			init_UART(9600);						//設定串列傳輸模式-9600bps
			ES=1;												//開啟串列中斷
			ET0=1;											//啟動計時器1
			EA=1;	                      //開啟總中斷
			TR0=1; 											//啟動計時器
	
			LCD_Init();									// LCD 初始化
			LCD_Cmd(LCD_CURSOR_ON);			// 將游標打開
			LCD_Chr(1,7,'8');						// LCD 在(1,7)位置顯示8
			LCD_Chr_Cp('0');						// LCD 在(1,8)位置顯示0
			LCD_Out_Cp("51");						// LCD 在(1,9)位置顯示51
			LCD_Cmd(LCD_CURSOR_OFF);		// 將游標關閉
			LCD_Out(1,1," ");	
			LCD_Out(2,1,"offline");			// LCD 在(2,1)位置顯示offline
			LCD_Out(2,15,"00");

			while(1)
			{
				SBUF=STX;
				Delay_ms(10);
				for(i=0;i<16;i++)
				{
					SBUF=SendBuf[i];					//傳送0-9
					Delay_ms(10);
				}
				SBUF=ETX;
				Delay_ms(10);
				Delay_ms(1000);
			}
}

執行結果:



沒有留言:

張貼留言