📄 io-uart.c
字号:
/********************************************************************************/
/* filename: uart.c */
/* version : v1.00 */
/* created : hw-chen */
/********************************************************************************/
#include "extern.h"
#define VM_XMIT_LEN 0x40
#define VM_XMIT_MSK 0x3F
#define VM_RXD P3_2 //* 需要利用外部中断0
#define VM_TXD P3_3
unsigned char data recv_vm_steps=0x0;
unsigned char data recv_vm_flags=0x0;
unsigned char data recv_vm_mdata=0x0;
unsigned char data recv_vm_sbuff=0x0;
unsigned char data xmit_vm_steps=0x0;
unsigned char data xmit_vm_flags=0x0;
unsigned char data xmit_vm_mdata=0x0;
unsigned char xmit_vm_buffer[VM_XMIT_LEN];
unsigned char xmit_vm_wr=0x0;
unsigned char xmit_vm_rd=0x0;
unsigned char recv_vm_buffer[VM_RECV_LEN];
unsigned char recv_vm_wr=0x0;
/********************************************************************************/
/* function : vm_io_initialize() */
/* created : hw-chen */
/* descript : 初始化虚拟串口 */
/********************************************************************************/
void vm_io_initialize(void)
{ EX0=0x1;
IT0=0x1; //* 设置INT0为下降沿中断方式
xmit_vm_steps=0x0;
xmit_vm_flags=0x0;
xmit_vm_mdata=0x0;
xmit_vm_wr =0x0;
xmit_vm_rd =0x0;
recv_vm_wr =0x0;
recv_vm_steps=0x0;
recv_vm_flags=0x0;
recv_vm_mdata=0x0;
}
/********************************************************************************/
/* fun_name : timer_0_initialize() */
/* descript : called by main initialize */
/* version : v1.00 */
/* created : hw-chen */
/* 1200的波特率,每位数据需要833.3US,每位数据的中间采样,起始位的中间只有一半 */
/* 的时间,定时器为416.667US,然后其他位都是833.3US */
/* 起始位:VALUE=65536-50000000x0.0004167/12=0xF938-0x10 */
/* 其它位:VALUE=65536-50000000x0.0008333/12=0xF270-0x10 */
/* 由于不是自动加载,需要减去系统的压栈和中断响应周期,查看汇编需要16指令周期 */
/********************************************************************************/
void timer_0_initialize(void)
{ TMOD &= 0xF0; //* TMOD: timer 0, mode 1, 16-bit load
TMOD |= 0x01; //* 模式1,16位模式
TR0 = 0x0;
}
/********************************************************************************/
/* function : timer_2_initialize() */
/* created : hw-chen */
/* descript : */
/* 由于采用VM串口的发送定时器,1200的波特率,每位定时0.8333MS=0.0008333S */
/* VALUE=65536-(oscxtime(s))/12=65536-50000000 x0.0008333/12(=3472 ) */
/* 定时器2处于16位自动加载模式,不会产生定时误差 */
/********************************************************************************/
void timer_2_initialize(void)
{ RCAP2H= 0xF2;
RCAP2L= 0x70;
TR2 = 0x01;
ET2 = 0x01;
}
/********************************************************************************/
/* function : extern_0_interrupt() */
/* created : hw-chen */
/* descript : */
/********************************************************************************/
void extern_0_interrupt(void) interrupt 0 using 1
{ vm_start_bit_check_start();
}
/********************************************************************************/
/* function : timer_0_interrupt() */
/* created : hw-chen */
/* descript : 用作VM串口接收处理 */
/********************************************************************************/
void timer_0_interrupt(void) interrupt 1 using 1
{ recv_mdata_isr_process();
}
/********************************************************************************/
/* function : timer_2_interrupt() */
/* created : hw-chen */
/* descript : 用作VM串口发送处理 */
/* 0.8333MS定时器 */
/********************************************************************************/
void timer_2_interrupt(void) interrupt 5 using 1
{ TF2=0; //* 需要自己清楚中断标记
xmit_mdata_isr_process(); //* 处理VM的ISR发送细节
}
/********************************************************************************/
/* function : main() */
/* created : hw-chen */
/* descript : */
/********************************************************************************/
void main(void)
{ timer_0_initialize();
vm_io_initialize();
timer_2_initialize();
EA =0x1;
ET2=0x1;
IT0=0x1;
ET0=0x1;
EX0=0x1; //* 打开外部VM-RXD管脚的中断
uart_printf("*********************************\r\n");
uart_printf("* VM UART start ... *\r\n");
uart_printf("*********************************\r\n");
while(1){
xmit_SBUF_mdata_process(); //* 发送SBUF的数据
recv_SBUF_mdata_process(); //* 接收SBUF的数据
}
}
/********************************************************************************/
/* function : xmit_SBUF_mdata_process() */
/* created : hw-chen */
/* descript : 发送数据处理,在主函数里面调用 */
/********************************************************************************/
void xmit_SBUF_mdata_process(void)
{ if((xmit_vm_flags)) //* 正在发送数据
{ return;
}
if((xmit_vm_rd==xmit_vm_wr))
{ return;
}
xmit_vm_mdata=xmit_vm_buffer[xmit_vm_rd];
xmit_vm_rd++;
xmit_vm_rd&=VM_XMIT_MSK;
VM_TXD=0x1; //* 起始位
xmit_vm_steps=0x0; //* 设置起始步
xmit_vm_flags=0x1; //* 启动发送,正在发送数据标记
}
/********************************************************************************/
/* function : xmit_mdata_isr_process() */
/* created : hw-chen */
/* descript : VM发送数据中断处理函数 */
/********************************************************************************/
void xmit_mdata_isr_process(void)
{ if((xmit_vm_flags)==0x0)
{ return;
}
xmit_vm_steps++;
switch(xmit_vm_steps)
{
case 0x1:
VM_TXD=0x0;
break;
case 0x2:
if((xmit_vm_mdata&0x1)==0x1)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x3:
if((xmit_vm_mdata&0x2)==0x2)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x4:
if((xmit_vm_mdata&0x4)==0x4)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x5:
if((xmit_vm_mdata&0x8)==0x8)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x6:
if((xmit_vm_mdata&0x10)==0x10)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x7:
if((xmit_vm_mdata&0x20)==0x20)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x8:
if((xmit_vm_mdata&0x40)==0x40)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0x9:
if((xmit_vm_mdata&0x80)==0x80)
VM_TXD=0x1;
else
VM_TXD=0x0;
break;
case 0xA:
VM_TXD=0x1;
break;
default:
VM_TXD=0x1;
xmit_vm_flags=0x0; //* 数据发送完毕
xmit_vm_steps=0x0; //* 复位起始步
break;
}
}
/********************************************************************************/
/* function : vm_start_bit_check_start() */
/* created : hw-chen */
/* descript : 设置VM开始位检测 */
/********************************************************************************/
void vm_start_bit_check_start(void)
{ EX0=0x0; //* 需要关闭外部VM-RXD管脚的中断
recv_vm_steps=0x0;
recv_vm_flags=0x0;
recv_vm_mdata=0x0;
TR0=0x00;
TH0=0xF9; //* 只需要一半的时间
TL0=0x48;
TR0=0x01;
}
/********************************************************************************/
/* function : recv_mdata_isr_process() */
/* created : hw-chen */
/* descript : 开始接收数据 */
/********************************************************************************/
void recv_mdata_isr_process(void)
{ TR0=0x00;
TH0=0xF2;
TL0=0x80;
TR0=0x01;
recv_vm_steps++;
switch(recv_vm_steps)
{
case 0x1:
if((VM_RXD)){
IE0=0x0; //* 必须清除这个标记
TR0=0x0; //* 禁止定时器
EX0=0x1; //* 打开外部VM-RXD管脚的中断
}
break;
case 0x2:
if((VM_RXD))
recv_vm_mdata|=0x1;
else
recv_vm_mdata&=0xFE;
break;
case 0x3:
if((VM_RXD))
recv_vm_mdata|=0x2;
else
recv_vm_mdata&=0xFD;
break;
case 0x4:
if((VM_RXD))
recv_vm_mdata|=0x4;
else
recv_vm_mdata&=0xFB;
break;
case 0x5:
if((VM_RXD))
recv_vm_mdata|=0x8;
else
recv_vm_mdata&=0xF7;
break;
case 0x6:
if((VM_RXD))
recv_vm_mdata|=0x10;
else
recv_vm_mdata&=0xEF;
break;
case 0x7:
if((VM_RXD))
recv_vm_mdata|=0x20;
else
recv_vm_mdata&=0xDF;
break;
case 0x8:
if((VM_RXD))
recv_vm_mdata|=0x40;
else
recv_vm_mdata&=0xBF;
break;
case 0x9:
if((VM_RXD))
recv_vm_mdata|=0x80;
else
recv_vm_mdata&=0x7F;
break;
case 0xA:
if((VM_RXD)){
recv_vm_flags=0x1;
}
recv_vm_sbuff=recv_vm_mdata;
IE0=0x0; //* 必须清除这个标记
TR0=0x0; //* 停止定时器
EX0=0x1; //* 打开外部VM-RXD管脚的中断
break;
default:
IE0=0x0; //* 必须清除这个标记
TR0=0x0; //* 停止定时器
EX0=0x1; //* 打开外部VM-RXD管脚的中断
break;
}
}
/********************************************************************************/
/* function : vm_printf() */
/* created : hw-chen */
/* descript : 从VM串口输出信息 */
/********************************************************************************/
void vm_printf(char *string, ...)
{ unsigned char i,length;
char buffer[0x40];
va_list arguments;
va_start(arguments,string);
vsprintf(buffer,string,arguments);
va_end(arguments);
length=strlen(buffer);
for(i=0x0;i<length;i++){
if((xmit_vm_wr+0x1)==xmit_vm_rd)
{ break;
}
xmit_vm_buffer[xmit_vm_wr]=buffer[i];
xmit_vm_wr++;
xmit_vm_wr&=VM_XMIT_MSK;
}
return;
}
/********************************************************************************/
/* function : recv_SBUF_mdata_process() */
/* created : hw-chen */
/* descript : VM串口接收数据处理 */
/********************************************************************************/
void recv_SBUF_mdata_process(void)
{ if(recv_vm_flags==0x0)
{ return;
}
recv_vm_flags=0x0;
if((recv_vm_sbuff==0x8)&&(recv_vm_wr>0x0)){ /* 处理退格 */
recv_vm_wr--;
vm_printf("%c",0x8);
vm_printf("%c",' ');
vm_printf("%c",0x8);
return;
}
recv_vm_buffer[recv_vm_wr]=recv_vm_sbuff; /* 接收处理 */
recv_vm_wr++;
if((recv_vm_sbuff=='\r')||(recv_vm_sbuff=='\n'))
{ recv_command_process();
}
if((recv_vm_wr>=VM_RECV_MSK))
{ recv_vm_wr=0x0;
}
else
{ vm_printf("%c",recv_vm_sbuff); /* 回显 */
}
}
/********************************************************************************/
/* function : recv_command_process() */
/* created : hw-chen */
/* descript : VM串口接收数据处理 */
/********************************************************************************/
void recv_command_process(void)
{ recv_vm_buffer[recv_vm_wr]=0x0;
//* 添加自己的处理函数
recv_vm_wr=0x0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -