这算是学习单片机的一个记录吧,惭愧毕业几年才开始捡起单片机。
————————————————————————————
进行串口通信需要做以下工作:
1)打开CPU的总中断EA;
2)打开串口通信的中断ES;
3)设置SCON寄存器采用哪一种的工作模式;
4)设置波特率;
5)选择定时器的工作方式。
使用的单片机型号STC8A8K64S4A12,实现字符串的发送与接收,向单片机发送一串字符,单片机就原样返回到PC。本来以为很简单,写完程序调试发现无法实现通信,查看该芯片的官方代码,发现需要加上P_SW1 = 0x00,原来用这个芯片需要RX、TX引脚设置。
外设端口切换寄存器1(P_SW1/AUXR1)
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 地址 |
S1_S1 | S1_S0 | CCP_S1 | CCP_S0 | SPI_S1 | SPI_S0 | 0 | DPS | a2H |
S1_S1和S1_S0决定UART1的端口选择:
S1_S1 | S1_S0 | 选择位 |
0 | 0 | RxD-P3.0 TxD-P3.1 |
0 | 1 | RxD-P3.6 TxD-P3.7 |
1 | 0 | RxD-P1.6 TxD-P1.7 |
1 | 1 | 无效 |
代码如下:
/****************串口通信****************/#include #include #include //包含延时函数#define uint unsigned int#define uchar unsigned charvoid Sendchar(uchar dat);void UartInit(void);void delay_ms(uint time2);void SendString(uchar *p);bit busy=0;//uchar re;uint k;uchar flag;uchar Buffer[50];void main(){P_SW1 = 0x00;//RXD/P3.0, TXD/P3.1UartInit();EA = 1;//打开总中断SendString("开始测试串口通信!");while(1){if(flag==1){SendString(Buffer);flag=0;k=0; // delay_ms(50);}}}//串口初始化,9600波特率void UartInit(void)//9600bps@22.1184MHz{PCON &= 0x7F;//波特率不倍速SCON = 0x50;//8位数据,可变波特率,选择模式1AUXR |= 0x40;//定时器时钟1T模式AUXR &= 0xFE;//串口1选择定时器1为波特率发生器TMOD &= 0x0F;//设置定时器模式TMOD |= 0x20;//设置定时器模式TL1 = 0xB8;//设置定时初始值TH1 = 0xB8;//设置定时重载值ET1 = 0;//禁止定时器%d中断TR1 = 1;//定时器1开始计时ES = 1;//打开串口中断}void Sendchar(uchar dat){while (busy);busy = 1;SBUF = dat;}void SendString(uchar *p){while(*p){Sendchar(*p++);}}void UART() interrupt 4{//串口中断号为4if (TI){TI = 0;busy = 0;}if(RI){RI=0;//清除接收中断标志//ES=0;//关闭串口中断Buffer[k++]=SBUF;//接收数据//re=SBUF;flag=1;//Buffer[i+1]='\0';} }/**********延时程序**************/void Delay1us()//@22.1184MHz ,STC-ISP系统生成的延时函数{unsigned char i;_nop_();i = 5;while (--i);}void delay_us(uint time1){//封装的1us函数接口uint i;for(i=0;i<=time1;i--){Delay1us();}}void Delay1ms()//@22.1184MHzSTC-ISP系统生成的延时函数{unsigned char i, j;i = 29;j = 183;do{while (--j);} while (--i);}void delay_ms(uint time2){//封装的1ms函数接口uint i;for(i=0;i<=time2;i--){Delay1ms();}}/**********************************/