📄 main.c
字号:
IIC_TxByte(0xa0);
IIC_WaitAck();
IIC_TxByte(addrInter);
IIC_WaitAck();
for(i=0;i<num;i++)
{
IIC_TxByte(buff[i]);
IIC_WaitAck();
}
IIC_Stop();
}
/*******************************************************************************
*** 函 数 名: extern void PCF8583_WriteByte(unsigned char addrInter,unsigned char val)
*** 功能描述: 对PCF8583写一个字节;
*** 全局变量: NO !
*** 输 入: addrInter:内部寻址;val:待写字节数据;
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 参照PCF8583读时序;
/******************************************************************************/
void PCF8583_WriteByte(unsigned char addrInter,unsigned char val)
{
IIC_Start();
IIC_TxByte(0xa0);
IIC_WaitAck();
IIC_TxByte(addrInter);
IIC_WaitAck();
IIC_TxByte(val);
IIC_WaitAck();
IIC_Stop();
}
void PCF8583_Init(void)
{
PCF8583_WriteByte(0x00,0x00); //Control reg. Alarm disabled。
}
/**************************************************************************************************
名称:SentByte
描述:字节数据传送子程序发送一个字节数据或地址给被控器PCF8574
**************************************************************************************************/
void sentbyte(unsigned char sentd)
{
unsigned char i;
for(i=0;i<8;i++) //要传送的数据长度为8 位
{
sentd<<=1; //要发送的数据左移
SDA=CY;
_nop_();
_nop_();
SCL=1; //置时钟线为高通知被控器开始接收数据位
_nop_(); //保证时钟高周期大于4 us
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0; //钳住总线准备接收下一个数据位
}
_nop_();
_nop_();
SDA=1; //8 位发送完后释放数据线准备收应答位
_nop_();
_nop_();
SCL=1; //开始接收应答信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //判断是否接收到应答信号正常转AckEnd
_nop_();
SCL=0; //发送结束钳住总线准备下一步发送或接收数据或进行其它处理
}
//*************************************************************************************************
//名称:SendData
//描述:发送1个字节数据给PCF8574
//************************************************************************************************
void senddata(unsigned char ucI)
{
unsigned char datauci=0;
IIC_Start();
sentbyte(slvadr);
datauci=ucI;
sentbyte(datauci);
IIC_Stop();
//delay_1ms(10);
}
unsigned char getbyte(void)
{
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--) {
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
/*unsigned char i,read;
SDA=1;
for(i=0;i<8;i++) //要传送的数据长度为8 位
{
SCL=1;
//_nop_();
//_nop_();
//_nop_();
CY=SDA;
read<<=1; //要发送的数据左移
//_nop_();
//_nop_();
//SCL=1; //置时钟线为高通知被控器开始接收数据位
//_nop_(); //保证时钟高周期大于4 us
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SCL=0; //钳住总线准备接收下一个数据位
}
_nop_();
_nop_();
SDA=1; //8 位发送完后释放数据线准备收应答位
_nop_();
_nop_();
SCL=1; //开始接收应答信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_(); //判断是否接收到应答信号正常转AckEnd
_nop_();
SCL=0; //发送结束钳住总线准备下一步发送或接收数据或进行其它处理
return read; */
}
//*********************************************************************************
// 地址为addr PCF8574 作为准双向口输出
//************************************************************************************
void output_control(unsigned char addr, unsigned char outdata)
{
slvadr=addr;
senddata(outdata);
}
unsigned char read(unsigned char addr)
{
unsigned char datauci=0;
IIC_Start();
sentbyte(addr);
IIC_Stop();
datauci=getbyte();
//sentbyte(datauci);
// while(1);
return datauci;
}
void delay2(unsigned char i)
{
while(--i);
}
main()
{unsigned char num=0, time[3],dat[2],sec[3];
unsigned int johu;
// init_serialcomm();
SCON = 0x40; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80; //SMOD=1;
TH1 = 0xFD;
TL1 = 0xFD; //Baud:19200 fosc=11.0592MHz
// IE |= 0x90; //Enable Serial Interrupt
TR1 = 1; // timer 1 run
// TI=1;
ce_62256=1;oe_62256=1;wr_62256=1;
dat[0]= 0x31;
dat[1]= 0x0c;
PCF8583_WriteDat(0x05,2,dat);
time[0]=0x55;
time[1]=0x59;
time[2]=0x23;
PCF8583_WriteDat(0x02,3,time);
TLC1456_clr=1;
while(1)
{
if (!(P2 & 0x10 ) )
{ delay2(200);//delay2(200);delay2(200);delay2(200);delay2(200);delay2(200);
if (!(P2 & 0x10 ) )
{ SendD(johu++,1) ;
SendD(johu++,0) ;
if (johu==255)
johu=0;
}
}
if (!(P2 & 0x08 ) )
{ delay2(200);//delay2(200);delay2(200);delay2(200);delay2(200);delay2(200);
if (!(P2 & 0x08 ) )
{
johu=get_ADC();
send_char_com((johu/1000)%10 + '0');
send_char_com((johu/100)%10 + '0');
send_char_com((johu/10)%10 + '0');
send_char_com((johu)%10 + '0');
send_char_com(0x0d);send_char_com(0x0a);
}
}
}
while(1)
{
if (!(P2 & 0x08 ) )
{ delay2(200);
if (!(P2 & 0x08 ) )
{
PCF8583_ReadDat(0x00,3,sec);
PCF8583_ReadDat(0x02,3,time);
PCF8583_ReadDat(0x05,2,dat);
send_char_com(0x0d);send_char_com(0x0a);
johu=read(0x41);
output_control(0x42,johu);
//output_control(0x40,0xf0);
send_char_com((johu/100)%10 + '0');
send_char_com((johu/10)%10 + '0');
send_char_com((johu)%10 + '0');
send_char_com(0x0d);send_char_com(0x0a);
send_char_com((dat[1] >> 4)/10 + '0');
send_char_com((dat[1] >> 4)%10 + '0');
send_char_com(' ');
send_char_com((dat[1] & 0x0f)/10 + '0');
send_char_com((dat[1] & 0x0f)%10 + '0');
send_char_com(' ');
send_char_com((dat[0] >> 4) + '0');
send_char_com((dat[0] & 0x0f) + '0');
//send_char_com((dat[0] & 0x0f)/10 + '0');
//send_char_com((dat[0] & 0x0f)%10 + '0');
send_char_com(0x0d);send_char_com(0x0a);
send_char_com(((time[2] >> 4) & 0x03) + '0');
send_char_com((time[2] & 0x0f) + '0');
send_char_com(':');
send_char_com((time[1] >> 4) + '0');
send_char_com((time[1] & 0x0f) + '0');
send_char_com(':');
send_char_com((time[0] >> 4) + '0');
send_char_com((time[0] & 0x0f) + '0');
send_char_com(' ');send_char_com(' ');send_char_com(' ');send_char_com(' ');
send_char_com(((sec[2] >> 4) & 0x03) + '0');
send_char_com((sec[2] & 0x0f) + '0');
send_char_com(':');
send_char_com((sec[1] >> 4) + '0');
send_char_com((sec[1] & 0x0f) + '0');
send_char_com(':');
send_char_com((sec[0] >> 4) + '0');
send_char_com((sec[0] & 0x0f) + '0');
/* send_char_com(time[0]);
send_char_com(time[1]);
send_char_com(time[2]);
send_char_com();send_char_com();send_char_com(); */
send_char_com(0x0d);send_char_com(0x0a);send_char_com(0x0d);send_char_com(0x0a);
}
}
}
while(1)
{
for (num=0;num<=254;num++)
{ ce_62256=0;oe_62256=1;wr_62256=0 ;
P0=num;
//ce_62256=1;
//wr_62256=1;
P1=255-num ;
ce_62256=1;oe_62256=1;wr_62256=1 ;
}
if (!(P2 & 0x08 ) )
{ wr_62256=1;
for (num=0;num<255;num++)
{
ce_62256=0;oe_62256=0;wr_62256=1 ;
P0=num;
P1=0xff;
send_char_com(P1);
ce_62256=1;oe_62256=0;wr_62256=1 ;
}
}
}
}
/*void delay2(unsigned char i)
{
while(--i);
}
为最佳方法。
分析:假设外挂12M(之后都是在这基础上讨论)
我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:
delay2(0):延时518us 518-2*256=6
delay2(1):延时7us(原帖写“5us”是错的,^_^)
delay2(10):延时25us 25-20=5
delay2(20):延时45us 45-40=5
delay2(100):延时205us 205-200=5
delay2(200):延时405us 405-400=5
见上可得可调度为2us,而最大误差为6us。
精度是很高了!
但这个程序的最大延时是为518us,显然不能满足实际需要,因为很多时候需要延迟比较长的时间。
那么,接下来讨论将t分配为两个字节,即uint型的时候,会出现什么情况。
void delay8(uint t)
{
while(--t);
}
我编译了下,传了些参数,并看了汇编代码,观察记录了下面的数据:
delay8(0):延时524551us 524551-8*65536=263
delay8(1):延时15us
delay8(10):延时85us 85-80=5
delay8(100):延时806us 806-800=6
delay8(1000):延时8009us 8009-8000=9
delay8(10000):延时80045us 80045-8000=45
delay8(65535):延时524542us 524542-524280=262
如果把这个程序的可调度看为8us,那么最大误差为263us,但这个延时程序还是不能满足要求的,因为延时最大为524.551ms。
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -