📄 serial.c
字号:
#include "240x.h"
#define uchar unsigned char
#define uint unsigned int
#define OLEN 50 /* size of serial transmission buffer */
uint outbuf[OLEN]; /* storage for transmission buffer */
uint *outlast=outbuf; //最后由中断传输出去的字节位置
uint *putlast=outbuf; //最后放入发送缓冲区的字节位置
#define ILEN 50 /* size of serial receiving buffer */
uint inbuf[ILEN];
uint *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置
uint *getlast=inbuf; //最后取走的字节位置
uint outbufsign0; //最后一个数据覵BUF发完标志 发完=0
uint outbufsign; //输出缓冲区非空标志 有=1
uint inbufsign; //接收缓冲区非空标志 有=1
uint inbufful; //输入缓冲区满标志 满=1
#define CR putstring("\r\n") //CR=回车换行
//*****************************
//放入一个字节到发送缓冲区
putbyte(char b)
{
SCICTL2 = SCICTL2 & 0xfc;
*putlast=b; //放字节进入缓冲区
putlast++; //发送缓冲区指针加一
if (putlast==outbuf+OLEN) putlast=outbuf; //指针到了顶部换到底部
outbufsign=1;
if (!outbufsign0) {outbufsign0=1;} //缓冲区开始为空置为有,启动发送
SCICTL2 = SCICTL2 | 0x03; //打开数据传送中断
asm (" INTR 30 ");//软件中断
}
//******************************
//放一串数据到发送缓冲区
putbytes(unsigned char *outplace,unsigned char j)
{ int i;
for(i=0;i<j;i++)
{putbyte(*outplace);
outplace++;
}
}
//******************************
//输出一个无符号字符数的十进制表示,必须标示小数点的位置,自动删除前面无用的零
//例如putchar(0x32,2),输出"4.8".
//putchar(0x32,3),输出"0.48".
//putchar(0x32,1),输出"48".
putchar(uchar c,uchar j)
{uchar freee[4];uchar i;
i=0;
freee[i++]=(c/100+0x30);
if (j==3) freee[i++]='.';
freee[i++]=(c%100)/10+0x30;
if (j==2) freee[i++]='.';
if (j==2 && freee[i-3]==0x30) freee[i-3]=0x20;
freee[i++]=(c%10)+0x30;
if (j==1 && freee[i-3]==0x30) freee[i-3]=0x20;
if (j==1 && freee[i-3]==0x20 && freee[i-2]==0x30) freee[i-2]=0x20;
putbytes(freee,i);
}
//******************************
//输出一个无符号整型数的十进制表示,必须标示小数点的位置,自动删除前面无用的零
putint(uint ui,uchar j)
{ uchar freee[6];
uchar i;
i=0;
freee[i++]=(ui/10000+0x30);
if (j==5) freee[i++]='.';
freee[i++]=((ui%10000)/1000+0x30);
if (j==4) freee[i++]='.';
if (j==4 && freee[i-3]==0x30) freee[i-3]=0x20;
freee[i++]=((ui%1000)/100+0x30);
if (j==3) freee[i++]='.';
if (j==3 && freee[i-4]==0x30) freee[i-4]=0x20;
if (j==3 && freee[i-4]==0x20 && freee[i-3]==0x30) freee[i-3]=0x20;
freee[i++]=((ui%100)/10+0x30);
if (j==2) freee[i++]='.';
if (j==2 && freee[i-5]==0x30) freee[i-5]=0x20;
if (j==2 && freee[i-5]==0x20 && freee[i-4]==0x30) freee[i-4]=0x20;
if (j==2 && freee[i-5]==0x20 && freee[i-4]==0x20 && freee[i-3]==0x30) freee[i-3]=0x20;
freee[i++]=(ui%10+0x30);
if (j==1 && freee[i-5]==0x30) freee[i-5]=0x20;
if (j==1 && freee[i-5]==0x20 && freee[i-4]==0x30) freee[i-4]=0x20;
if (j==1 && freee[i-5]==0x20 && freee[i-4]==0x20 && freee[i-3]==0x30) freee[i-3]=0x20;
if (j==1 && freee[i-5]==0x20 && freee[i-4]==0x20 && freee[i-3]==0x20 && freee[i-2]==0x30) freee[i-2]=0x20;
putbytes(freee,i);
}
//***************************************
//发送一个定义在存储区的字符串到串口
putstring(unsigned char *puts)
{
for (;*(puts)!=0;puts++) //遇到停止符0结束
putbyte(*puts);
putbyte(0x0d);
}
//*************************************
//发送一个字节的hex码,分成两个字节发。
unsigned char hex_[]={"0123456789ABCDEF"};
puthex(char c)
{
int ch;
ch=(c>>4)&0x0f;
putbyte(hex_[ch]);
ch=c&0x0f;
putbyte(hex_[ch]);
}
//*************************************
//从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。
uchar getbyte (void)
{ char c ;
while (!inbufsign); //缓冲区空等待
SCICTL2 = SCICTL2 & 0x0FC;
c= *getlast; //取数据
getlast++; //最后取走的数据位置加一
inbufful=0; //输入缓冲区的满标志清零
if (getlast==(inbuf+ILEN)) getlast=inbuf; //地址到顶部回到底部
if (getlast==inlast) inbufsign=0; //地址相等置接收缓冲区空空标志,再取数前要检该标志
SCICTL2 = SCICTL2 | 0x03;
return (c); //取回数据
}
//*****************************************
//接收一行数据,必须定义放数据串的指针位置和大小 del=0x7f,backspace=0x08,cr=0x0d,lf=0x0a
void getline (uchar *line, unsigned char n)
{ unsigned char cnt = 0; //定义已接收的长度
char c;
do {
if ((c = getbyte ()) == 0x0d) c = 0x00; //读一个字节,如果是回车换成结束符
if (c == 0x08 || c == 0x7f) //BACKSPACE 和 DEL 的处理
{ if (cnt != 0) //已经输入退掉一个字符
{cnt--; //总数目减一
line--; //指针减一
putbyte (0x08); //屏幕回显的处理
putbyte (' ');
putbyte (0x08);
}
}
else
{ putbyte (*line = c); //其他字符取入,回显
*line = c;
line++; //指针加一
cnt++; //总数目加一
}
} while (cnt < n - 1 && c != 0x00 && c!=0x1b); //数目到了,回车或ESC停止
*line = 0; //再加上停止符0
}
//****************************
//人工输入一个字符到输入缓冲区
putinbuf(uchar c)
{
SCICTL2 = SCICTL2 & 0x0FC;
if(!inbufful)
{*inlast= c; //放入数据
inlast++; //最后放入的位置加一
if (inlast==inbuf+ILEN) inlast=inbuf;//地址到顶部回到底部
if (inlast==getlast) inbufful=1; //接收缓冲区满置满标志
inbufsign=1;
}
SCICTL2 = SCICTL2 | 0x03;
}
//*****************************************
//串口中断处理
//发送中断处理
interrupt void c_int5(void)
{
if(SCICTL2 & 0x80)
{
if(outbufsign)
{
SCITXBUF = *outlast; //未发送完继续发送
outlast++; //最后传出去的字节位置加一
if (outlast==(outbuf+OLEN)) outlast=outbuf;//地址到顶部回到底部
if (putlast==outlast) outbufsign=0; //数据发送完置发送缓冲区空标志
}
else
{
outbufsign0=0;
SCICTL2 = SCICTL2 & 0x0fe;//数据传送完毕关闭传送中断
}
}
if(SCIRXST & 0x40) //接收中断处理
if(!inbufful)
{
*inlast = SCIRXBUF; //放入数据
inlast++; //最后放入的位置加一
inbufsign=1;
if (inlast==(inbuf+ILEN)) inlast=inbuf;//地址到顶部回到底部
if (inlast==getlast) inbufful=1; //接收缓冲区满置满标志
}
}
//*****************************
//串口初始化
serial_init ()
{
SCSR1 = SCSR1 | 0x40;
MCRA = MCRA | 0x03;
SCICCR = 0x07;//
SCICTL1 = 0x03;//控制寄存器
SCICTL2 = SCICTL2 | 0x03;
//SCIHBAUD = 0x0;//传口波特率 baud=38400
//SCILBAUD = 0x081;//传口波特率
SCIHBAUD = 0x02;//传口波特率 buad=9600
SCILBAUD = 0x07;//传口波特率
//计算公式 BRR=cpuclk/(baud*8)-1
SCIPRI = 0x0ff; //串口中断优先级设置
SCICTL1 = 0x23;
IMR = IMR | 0x010;
IFR = 0x0FFFF;
asm(" CLRC INTM"); /// Enable all interrupt
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -