今天解决了两个问题。
一个是占空比调速。这个用的是timer0中断,计数器计数,到100中断一次,10次进行一次速度调节,比较简单。
一个是串口接收字符串控制命令,即增加控制的稳定器,路由器启动或者被动重启的时候小车不至于乱串。
串口程序得到的经验有两点:
1,子函数都加上return吧,不然说不定什么时候就断线了,不回到主函数中。
2,逻辑关系一定不能有错误,今天因为计数错误耽误了不少时间。
遗留问题:
1,UART_send_byte()中最后 TI 为何要置1没想明白,就像串口接收的时候最后要把 TI 清零一样,不知道有什么作用,但是不这样做串口就是不接收数据。
2,在中断函数中调用UART_send_byte(),一次可以执行,但连续调用两次的话,函数就不再执行,不明白原因。
附源程序:
占空比:
- //timer0初始化
- void inittimer0(void)
- {
- ET0=1; //允许timer0中断
- //工作方式由串口初始化时同时设置,方式1
- TH0=0xFF;
- TL0=0x9C; //定时器赋初值,100机器周期溢出一次
- TR0=1; //开启timer0计数
- }
- //timer0中断函数
- void timer0() interrupt 1
- {
- click++;
- TH0=0xFF;
- TL0=0x9C;
- //重新赋初值
- TR0=1; //定时器开始下一次计数
- }
- void main()
- {
- ……;
- ……;
- while(1)
- {
- if(click<=dutycycles)
- P2=p2mark;
- else if(click<=10)
- P2=0xF0;
- else click=1;
- }
- }
串口通讯:
- //通信解码
- //编码格式:#0A#(0x23 0x30 0x41 0x23)
- 行走动作
- void Communication_Decode(void)
- {
- //UART_send(buffer,3);
- if(buffer[0]==0x30)//动作判断位’0′
- {
- switch(buffer[1])//执行具体动作
- {
- case 0x41:
- p2mark=0xF5;
- return;
- case 0x42:
- p2mark=0xF9;
- return;
- case 0x43:
- p2mark=0xF6;
- return;
- case 0x44:
- p2mark=0xFA;
- return;
- case 0x45:
- p2mark=0xF0;
- return;
- default:
- return;
- }
- }
- else
- return;
- }
- //接收串口数据,符合要求的为4位字符串
- void UART_Interrupt_Receive(void) interrupt 4
- {
- int i;
- if(RI==1)//中断接收打开,进入接收
- {
- RI=0;//开始接收串口数据,RI清0
- if(rec_flag==0) //标志为0,等待接收数据
- {
- if(SBUF==0x23) //缓冲区为0x23(#),表示有命令数据,标志置1,i置0,开始接收下一个,第一位丢弃
- {
- rec_flag=1;
- i=0;
- }
- }
- else//如果标志为1,正在接收数据
- {
- if(SBUF==0x23)//如果缓冲区为0x23(#),接收完成
- {
- rec_flag=0; //标志置0
- if(i==2) //如果i=2,数据已经接收完毕,开始解码,不为3位表示接收的不是命令字符,不需要解码
- {
- Communication_Decode();
- }
- i=0; //解码完成后i置0
- }else //如果正在接收数据时缓冲区不为0x23,即接收进行中
- {
- buffer[i]=SBUF; //从SBUF读入数据
- //UART_send_byte(buffer[i]);
- //UART_send_byte(buffer[1]);
- i++;
- }
- }
- }
- else
- {
- TI=0; //中断接收未打开,进入发送中断
- }
- }