请教一个51串口通信的问题
时间:12-12
整理:3721RD
点击:
本意是设计一个交互的串口通信程序,以前没有写过单片机程序,遇到一些问题来请教大家。
单独的收和发都是好的,但同时启动收发时,主程序得不到执行,推断应该是一直在中断中,但不知道是什么原因引起的,如何清掉,还请指教,谢谢!
#include <reg51.h>
#include <stdio.h>
#include <string.h>
#define FOSC 40000000
#define BUF_LEN 10
static unsigned char prompt[4] = {0x0d, 0x0a, '$', ' '};
static unsigned char inbuf[BUF_LEN]; // last 2 char: 0x0d, 0x0a
static unsigned char incount = 0, inlen = 0;
static bit read_flag = 0;
void delay_1ms(void) //1ms延时函数,不一定准哈,只是delay一下
{
unsigned int i;
for (i=0; i<40000/12; i++);
}
void delay_nms(unsigned int n) //N ms延时函数
{
unsigned int i=0;
for (i=0; i<n; i++)
delay_1ms();
}
static void init_serialcomm(void)
{
PCON |= 0x80; // SMOD=1;
SCON = 0x50 ; // SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD &= 0x0f; // TMOD: timer 1, mode 2, 8-bit reload
TMOD |= 0x20;
TH1 = 240 ; // TH1: Baud:9600 fosc=40MHz. 0xea=234 can not work...
TL1 = TH1; // TL1: init Timer1
TR1 = 1 ; // TCON: timer 1 run
TI = 1; // SCON: Indicate TX0 ready
IE |= 0x90; // Enable Serial Interrupt
ES = 1; // IE: Enable serial recv
}
//向串口发送一个字符
static void send_char_com(unsigned char ch)
{
SBUF = ch;
while (TI == 0);
TI = 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
static void send_string_com(unsigned char *str, unsigned int strlen)
{
unsigned int k = 0;
do {
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
//串口接收中断函数
static void serial() interrupt 4 using 3
{
unsigned char ch;
ES = 0; // 关串口中断
/* send_char_com('?'); */
if (RI) {
IE = 0;
RI = 0; // 软件清除接收中断
ch = SBUF;
send_char_com(ch); // echo
inbuf[incount++] = ch;
if (incount > BUF_LEN-2) { // leave last char to append 0x0a
incount = BUF_LEN-2;
}
if (ch == 0x0d) {
send_char_com(0x0a);
inbuf[incount++] = 0x0a;
read_flag = 1;
inlen = incount;
incount = 0;
// test
send_string_com(inbuf, inlen); // for test
}
}
TI = 0; // ???
ES = 1; // 开串口中断
}
void main (void)
{
init_serialcomm();
EA = 1; // enable global interrupts
send_string_com(prompt, 4);
while (1) {
/* send_char_com('+'); */
/* if (read_flag) { //如果取数标志已置位,就将读到的数从串口发出 */
/* send_string_com(inbuf, inlen); */
/* read_flag = 0 ; //取数标志清0 */
/* send_string_com(prompt, 4); */
/* } */
delay_nms(50);
send_char_com('.');
}
}
单独的收和发都是好的,但同时启动收发时,主程序得不到执行,推断应该是一直在中断中,但不知道是什么原因引起的,如何清掉,还请指教,谢谢!
#include <reg51.h>
#include <stdio.h>
#include <string.h>
#define FOSC 40000000
#define BUF_LEN 10
static unsigned char prompt[4] = {0x0d, 0x0a, '$', ' '};
static unsigned char inbuf[BUF_LEN]; // last 2 char: 0x0d, 0x0a
static unsigned char incount = 0, inlen = 0;
static bit read_flag = 0;
void delay_1ms(void) //1ms延时函数,不一定准哈,只是delay一下
{
unsigned int i;
for (i=0; i<40000/12; i++);
}
void delay_nms(unsigned int n) //N ms延时函数
{
unsigned int i=0;
for (i=0; i<n; i++)
delay_1ms();
}
static void init_serialcomm(void)
{
PCON |= 0x80; // SMOD=1;
SCON = 0x50 ; // SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD &= 0x0f; // TMOD: timer 1, mode 2, 8-bit reload
TMOD |= 0x20;
TH1 = 240 ; // TH1: Baud:9600 fosc=40MHz. 0xea=234 can not work...
TL1 = TH1; // TL1: init Timer1
TR1 = 1 ; // TCON: timer 1 run
TI = 1; // SCON: Indicate TX0 ready
IE |= 0x90; // Enable Serial Interrupt
ES = 1; // IE: Enable serial recv
}
//向串口发送一个字符
static void send_char_com(unsigned char ch)
{
SBUF = ch;
while (TI == 0);
TI = 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
static void send_string_com(unsigned char *str, unsigned int strlen)
{
unsigned int k = 0;
do {
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
//串口接收中断函数
static void serial() interrupt 4 using 3
{
unsigned char ch;
ES = 0; // 关串口中断
/* send_char_com('?'); */
if (RI) {
IE = 0;
RI = 0; // 软件清除接收中断
ch = SBUF;
send_char_com(ch); // echo
inbuf[incount++] = ch;
if (incount > BUF_LEN-2) { // leave last char to append 0x0a
incount = BUF_LEN-2;
}
if (ch == 0x0d) {
send_char_com(0x0a);
inbuf[incount++] = 0x0a;
read_flag = 1;
inlen = incount;
incount = 0;
// test
send_string_com(inbuf, inlen); // for test
}
}
TI = 0; // ???
ES = 1; // 开串口中断
}
void main (void)
{
init_serialcomm();
EA = 1; // enable global interrupts
send_string_com(prompt, 4);
while (1) {
/* send_char_com('+'); */
/* if (read_flag) { //如果取数标志已置位,就将读到的数从串口发出 */
/* send_string_com(inbuf, inlen); */
/* read_flag = 0 ; //取数标志清0 */
/* send_string_com(prompt, 4); */
/* } */
delay_nms(50);
send_char_com('.');
}
}