在OURDEV得到很多帮助,不敢藏私,也奉上 我的C8051F采用串口0 中断发送+缓冲区 的方式写的小程序吧~
请大家多多指教~~
主要原理:
上层直接将数据装入缓冲区,若手工发送标记(auto_uart0_tx_flg )为1,则置位串口中断标志TI0,启动发送,直至缓冲区为空(读写指针相等,此时将auto_uart0_tx_flg置0),否则,说明此时缓冲区中仍有数据,不用任何操作。
我的主要功能模块:
/*
********************************************************************************
*
* void UART0_Init (void);
* UART0配置
* Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
*
********************************************************************************
*/
void UART0_Init (void)
{
SCON0 = 0x50; // SCON0: mode 1, 8-bit UART, enable RX
TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1 = -(SYSCLK/BAUDRATE/16); // set Timer1 reload value for baudrate
TR1 = 1; // start Timer1
CKCON |= 0x10; // Timer1 uses SYSCLK as time base
PCON |= 0x80; // SMOD00 = 1,倍频
// PCON |= (1 << 6); //
// TI0 = 1; // Indicate TX0 ready
in_uart_tx_buf = uart_tx_buf;
out_uart_tx_buf = uart_tx_buf;
}
/*
********************************************************************************
*
* void UART0_ISR(void);
* USART0中断处理函数.
*
********************************************************************************
*/
void UART0_ISR(void) interrupt iv_UART0
{
if(RI0)//是接收中断
{
RI0 = 0;//清接收中断标志位
uart_data = SBUF0;//保存接收到的数据
uart_rcv_data_flag = 1;//标志位置1
}
if(TI0)//是发送中断
{
TI0 = 0;//清发送中断标志位,big problem
uart_out_tx_buf();
}
}
//进入发送中断后调用uart_out_tx_buf进行后续的处理
void uart_out_tx_buf(void)
{
if(out_uart_tx_buf == in_uart_tx_buf) //txbuf为空
{
ES0 = 0;
auto_uart0_tx_flg = 1;//本次发送结束,下次还须手动触发
return;
}
SBUF0 = *out_uart_tx_buf;
out_uart_tx_buf++;
if(out_uart_tx_buf == (uart_tx_buf + uart_tx_buf_len)) //缓冲区回绕
out_uart_tx_buf = uart_tx_buf;
}
//上层程序调用串口发送数据的接口
void uart_in_tx_buf(INT8U *pt,INT8U datalen)
{
INT8U *t,*p;
t = in_uart_tx_buf;
p = pt;
while(datalen--)
{
t++;
if(t == (uart_tx_buf + uart_tx_buf_len)) //回绕
t = uart_tx_buf;
if(t == out_uart_tx_buf) //txbuf满
return;
*in_uart_tx_buf = *p++;
in_uart_tx_buf = t;
}
uart_tx_start();
}
//手动启动串口发送
void uart_tx_start(void)
{
if(auto_uart0_tx_flg == 1)
{
ES0 = 1;
TI0 = 1;
auto_uart0_tx_flg = 0;
}
}
/*
********************************************************************************
*
* MAIN
*
********************************************************************************
*/
void main(void)
{
INT8U i;
ALL_DEVICE_Init();//初始化,开全局中断等
for(i=0;i<8;i++)
{
uart_in_tx_buf("helloworld",10);
// delay(100);
}
// uart_in_tx_buf("helloworld helloworld helloworld",32);
while(1);
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
-----------------------------------------------------------------------
我这没有,朋友能把这个程序给我一份吗?zj_yang1983@163.com
请楼主帮忙看下。。。谢谢
/****************************************************************
*
*UART1初始化
*****************************************************************/
void UART1_Init (void)
{
SBRLL1 =0X8F;
SBRLH1 =0XFD; //波特率 9600 内部12M 晶振
SCON1 =0X30; //允许接收,准备好接收
SMOD1 =0X6C; //8位数据位,无奇偶校验,一位停止位;
SMOD1 |=0X80;
SBCON1 =0X43; //使能UART1,1分频
EIE2 |=0x02;
}
/*****************************************************************
*
*端口初始化函数
*****************************************************************/
void Port_IO_Init(void)
{
P0SKIP = 0xC3; //
P1SKIP = 0x08;
XBR0 = 0x05; //P0.4 P0.5接到串口0上,SMBus 连接到P0.2、P0.3口上
XBR1 = 0x70; //交叉开关、T0、T1使能
XBR2 = 0x01; //UART1的 RXD1、TDX1分别接到P1.4、P1.2上
//P1MDOUT = 0x00;
}
/*****************************************************************
*
*系统初始化
*****************************************************************/
void System_Init(void)
{
//uint i;
PCA0MD &= ~0x40; //关闭看门狗定时器
OSCICN |= 0x03; //内部高频振荡器使能且振荡器按编程频率来运行
Port_IO_Init();
//T0_model_2ms_init();
//UART0_Init ();
UART1_Init ();
}
一周热门 更多>