上手了一块STC8A8K64S4A12,STC公司推出的最新的单片机,性能比51要好非常多。详细的芯片信息可以在官网搜到。
链接:http://www.stcisp.com/_datasheet_STC8F8K.html
目前还没使用到高级的功能,只使用了串口功能,上手感觉和51没太大差别。逻辑一致,需要注意的是里面一些寄存器的配置,跟51有些区别,可以在stc-isp下载器那里查询相关的程序,直接套用即可。
使用串口之前要先看看相关的寄存器配置,直接套用网上的例程可能会出错。我本次使用了两个定时器,定时器1作为串口1的波特率发送器,另开定时器2作为计时使用。使用定时器要考虑寄存器的赋值问题,刚开始使用我在两个定时器的初始化函数里面都对AUXR寄存器进行了赋值,导致跑程序时AUXR的值在两个初始化函数里面切来切去,整个功能都无法实现。
/***************************************************/
void UartInit(void) //[email protected]
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xB2; //设定定时初值
TH1 = 0xB2; //设定定时器重装值
//ET1 = 0; //禁止定时器1中断
EA = 1; //开总中断
TR1 = 1; //启动定时器1
ES=1; //开串口中断
SBUF='B'; //先往串口数据缓存器里面塞东西
}
注意里面AUXR寄存器的配置,搞清楚&=和|=的区别。
例如 0x40=0100 0000; AUXR|=0x40;就是保证第2位(上图B6位)为1,而其他7位的数值不受影响;
0xFE=1111 1110;AUXR &= 0xFE; 就是确保最后一位(上图B0)为0,其他7位的数值不受影响;
简单来说|=是为了把某个位 置1,而&=是为了把某个位 置0 ;
void usart_isr() interrupt 4 //串口1中断服务函数
{
if(TI) //判断发送
{
P22=!P22;
TI=0;
}
if(RI) //判断接收
{
P55=!P55;
RI=0;
}
}
void Send_string(uint dat) //串口发送数据
{
SBUF=dat;
while(TI==0);
//while(!TI) //另一种方式
TI=0;
}
需要注意SBUF,这是51单片机的串口数据缓存器——两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。
当SBUF='a',说明往发送缓存器送了字符a,意味着发送。
当b=SBUF,说明b变量被赋了SBUF里面的数值,意味着接收。
/********************************************/
void Timer5Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x44; //定时器时钟1T模式 当时修改为0x44主要是怕对定时器1的配置造成干扰
//AUXR |= 0x04; //定时器时钟1T模式 原版
T2L = 0x40; //设置定时初值
T2H = 0xA2; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2 = ET2; //使能定时器中断
}
void TM2_Isr() interrupt 12 using 1
{
count_flag++;
if(count_flag==1000)
{
P24=!P24;
count_flag=0;
AUXINTIF &= ~T2IF; //清中断标志
}
}
以上两个函数均从STC-ISP下载器里面的例程复制过来的。好资源要懂得利用。
要注意开启定时器的计时功能,要开启中断;之前忘了加进去了,查了一个晚上,还以为是寄存器干扰问题。经大佬指点才知道忘开中断了。************************************* IE2 = ET2; //使能定时器2中断
当多个函数共同使用到同一个寄存器时,要注意赋值问题,否则会出现多次重置寄存器的情况,导致程序跑飞。所以官网数据手册尤为重要,要清楚知道一个位的功能和作用。