📄 serial.c
字号:
/*
黄 clock 5 红
绿 data 1 黑
黑 地 3
*/
#include <reg51.H>
#include <stdio.h>
#include <string.h>
#include "delay.h"
typedef unsigned char UCHAR;
typedef unsigned long ULONG;
#define TRUE 1
#define FALSE 0
//UCHAR ucData = 0,i=0;
UCHAR gucBuf[16] = {0};
UCHAR* pBuf = gucBuf;
//bit isDataReady=0;
//bit canReceive=1;
sbit P1_0 = P1^0;
sbit P2_0 = P2^0;
sbit CLK_SND = P1^1;
sbit DAT_SND = P1^2;
//sbit CLK_RCV = P3^2;
sbit CLK_RCV = P1^3;
sbit DAT_RCV = P1^0;
ULONG tick = 0, prevtick = 0;
#define LED P0
UCHAR bitCount = 0;
bit checkP(UCHAR fr);
void rcvBit(UCHAR i);
void exint0_isr(UCHAR i);
idata UCHAR bTmp[80]={0};
UCHAR frCount = 0;
UCHAR rcvFrCount = 0;
/*
1) Set/Reset Data
2) Delay 20 microseconds
3) Bring Clock low
4) Delay 40 microseconds
5) Release Clock
6) Delay 20 microseconds
*/
void sendBit(bit b)
{
//bTmp[frCount]=b;
//frCount++;
DAT_SND=b;
delay_u(20);
CLK_SND=0;
delay_u(40);
CLK_SND=1;
delay_u(20);
}
/*
1) Wait for Clock = high.
2) Delay 50 microseconds.
3) Clock still = high?
No--goto step 1
4) Data = high?
No--Abort (and read byte from host)
5) Delay 20 microseconds (=40 microseconds to the time Clock is pulled low in sending the start bit.)
6) Output Start bit (0) \ After sending each of these bits, test
7) Output 8 data bits > Clock to make sure host hasn't pulled it
8) Output Parity bit / low (which would abort this transmission.)
9) Output Stop bit (1)
10) Delay 30 microseconds (=50 microseconds from the time Clock is released in sending the stop bit)
*/
void sendFrame(UCHAR fr)
{
UCHAR i;
while(!CLK_SND)
{
//delay_u(50);
}
//if(!CLK_SND) return;
if(!DAT_SND) return;
delay_u(20);
sendBit(0);
for(i=0;i<8;i++)
{
sendBit(fr&(1<<i));
}
sendBit(checkP(fr));
sendBit(1);
delay_u(30);
}
bit checkP(UCHAR fr)//奇校验
{
bit b=1;
UCHAR i=0;
for(;i<8;i++)
{
b^=(fr&0x01);
fr>>=1;
}
return b;
}
void clock_init() reentrant using 0
{
TR0=0;
TF0=0;
TH0=0xDB;//10ms
TL0=0xF0;
//TH0=0XFC;
//TL0=0X18;
TR0=1;
}
bit rcvFrame(UCHAR* pucData)
{
UCHAR i;
UCHAR ucData = 0,ucDataTmp = 0;
//while(CLK_RCV);
//if(CLK_RCV) return FALSE;//时钟为高,表明没有数据
//ucData = 0;
//首位
while(CLK_RCV);//等待时钟线变低
while(!CLK_RCV);//等待时钟线变高
//8个数据位
for(i=0;i<8;i++)
{
while(CLK_RCV);//等待时钟线变低
ucDataTmp = ucDataTmp<<1;
ucDataTmp|=DAT_RCV;
while(!CLK_RCV);//等待时钟线变高
}
//奇校验位
while(CLK_RCV);//等待时钟线变低
while(!CLK_RCV);//等待时钟线变高
//末位
while(CLK_RCV);//等待时钟线变低
while(!CLK_RCV);//等待时钟线变高
CLK_RCV = 0;//拉低时钟抑制发送,进行字节序转换
for(i=0;i<8;i++)
{
ucData=ucData<<1;
ucData|=(ucDataTmp&0x01);
ucDataTmp=ucDataTmp>>1;
}
*pucData = ucData;
printf("\r\n%bu,0x%bx",ucData,ucData);
CLK_RCV = 1;
return TRUE;
}
/*
void rcvBit(UCHAR i)
{
while(CLK_RCV);//等待时钟线变低
//CLK = 0;//有数据,拉低时钟,抑制键盘发送,进行处理
//exint0_isr(i);
if(1<=i&&i<=8)
{
ucData = ucData<<1;
ucData|=DAT_RCV;
}
//CLK = 1;//处理完一位,释放时钟
while(!CLK_RCV);//等待时钟线变高
}*/
void main(void)
{
//long j;
//unsigned char a;
//UCHAR j;
//UCHAR ucBuf[16];
UCHAR ucData;
bit bRet;
//sendFrame(0x87);
SCON = 0xD8; //串口方式1,允许接收
TMOD |= 0x20; //定时器1 定时方式2
TH1 = 0xFD; //12MHz 9600 波特率
TL1 = 0xFD;
TI = 1;
TR1 = 1; //启动定时器
//定时器0初始化
TMOD|=0X01;
TF0=0;
clock_init();
ET0=1;
EA = 1;
IT0=1;
EX0=1;
while(1)
{
//CLK_RCV =1;
bRet = rcvFrame(&ucData);
sendFrame(ucData);
//CLK_RCV = 0;
//if(bRet)
// printf("\r\n%bu,0x%bx",ucData,ucData);
/*sendFrame(0x1c);
delay_u(200);
sendFrame(0xf0);
delay_u(200);
sendFrame(0x1c);
delay_u(200);*/
//while(!isDataReady);
/*
if(!P2_0)//50ms打印一次
{
EA=0;
memcpy(ucBuf,gucBuf,sizeof(ucBuf));
EA=1;
for(j=0;j<rcvFrCount;j++)
{
//if(ucBuf[j]==0) break;
printf("\r\n%bu,0x%bx",ucBuf[j],ucBuf[j]);
EA=0;
pBuf = gucBuf;
memset(gucBuf,0,sizeof(gucBuf));
rcvFrCount = 0;
EA=1;
}
}*/
//ucData=0;
//isDataReady=0;
//i=0;//启动接收
/*if(!P2_0) i=0;
P0=ucData;*/
};
}
void clk_int() interrupt 1 using 0
{
EA=0;
tick++;
//if(0==(tick%100)) printf("1");
clock_init();
EA=1;
}
//idata char c[100] = {0};
#if 0
void exint0_isr(UCHAR i) //interrupt 0 using 0
{
//CLK_RCV = 0;
EA=0;
bitCount++;
LED=bitCount;
//c[0]=0;
/*if(strlen(c)>90)
printf("%s",c);
if(tick-prevtick>5)//超过50ms,新启一帧
{
strcat(c,"\r\n");
}
if(P1_0)
strcat(c,"1");
else
strcat(c,"0");
prevtick = tick;*/
/*
if(tick-prevtick>5)//超过50ms,新启一帧
{
i=0;
ucData=0;
}
*/
//while(!canReceive)
if(0==i)
{
//prevtick = tick;
//if(0!=DAT_RCV) goto RET;//首位应为0,否则返回继续等待首位
}
else if(1<=i&&i<=8)
{
if(DAT_RCV)
{
ucData|=(1<<(i-1));
}
else
{
ucData|=(0<<(i-1));
}
/*if(8==i)
{
printf("\r\n%bu,0x%bx",ucData,ucData);
}*/
}
else if(9==i)//奇偶检验位
{
}
else if(10==i)//停止位
{
/*if(1!=P1_0)
{
return;
//printf("\r\n接受停止位出错!");
}*/
//ucData=0;
//i=0;
//isDataReady = 1;
/**pBuf = ucData;
rcvFrCount++;
pBuf++;*/
//ucData=0;
//i=0;//启动接收
goto RET;
}
else goto RET;
//i++;
RET:
EA=1;
//CLK_RCV = 1;
return;
}
#endif
/*void delay_u(UCHAR t)
{
UCHAR i;
for(i=0;i<t;i++);
}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -