马老师 模拟I2C总线 读写2402的问题
马老师:我用的16的AVR写的口线模拟I2C读写2402的程序,为什么写进去的时候判断回应位可以的,读2402时判断回应位就有问题了。因为我原来用162写2402的,PD4,PD5做SDA,SCL但是有问题。所以我又用16试的,选择PA0做SCL,PA1做SDA 别的口线复用功能太多,我也不知道有没有屏蔽掉。以下是源程序
//ICC-AVR application builder : 2007-5-29 9:41:16
// Target : M16
// Crystal: 11.059Mhz
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
//***************************************************************
//通讯部分的参数定义
//***************************************************************
char data_send; //要发送的数据
char data_rev; //接收的所有数据的数组
char send_step; //发送数据步数
char rev_lenth; //接收到的数组长度
char rev_counter; //接收数据总计数器
char data_counter; //接收的数组计数器
char check; //校验码
char send_counter;
char eep_test;
char eep_test2;
char i2cr;
char i2cs;
char mydata;
//****************************************************************
//处理接受数据的参数定义
//****************************************************************
char nm_24c02; //从24C02读出的全部内码数组
char i2cr; //存放从24C02读出的一个字节数据
char i2cs;
//****************************************************************
//时间参数定义
//***************************************************************
char count_20ms; //20MS计数器
//****************************************************************
struct data
{
unsigned bit0:1; //发送开始标志位
unsigned bit1:1; //接收完成标志位
unsigned bit2:1; //发送成功标志位
unsigned bit3:1; //接收开始标志位
} sign,time;
unsigned int count_1ms;
void port_init(void)
{
PORTA = 0xFF;
DDRA= 0xFF;
PORTB = 0xFF;
DDRB= 0x0F;
PORTC = 0xff; //m103 output only
DDRC= 0x03;
PORTD = 0x00;
DDRD= 0x03;
}
//TIMER0 initialisation - prescale:64
// WGM: Normal
// desired value: 1mSec
// actual value:0.995mSec (0.5%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x54; //set count
OCR0= 0xAC; //set compare
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x54; //reload counter value
count_20ms++;
if(count_20ms>=20)
{
time.bit0=1; //20ms
count_20ms=0;
}
TCCR0 = 0x03; //start timer
}
//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9600 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = 0x86;
UBRRL = 0x47; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0xD8;
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
char recieve_data; //每次接收数据的缓冲器
//uart has received a character in UDR
recieve_data=UDR;
switch(rev_counter)
{
case 0: if (recieve_data==0xfe)
{
rev_counter++;
//PORTA|=0xfC;
check+=0XFE;
}
else
{
check=0;
rev_counter=0;
}
break;
case 1: if(recieve_data==0xfe)
{
rev_counter++;
//PORTA=0XFD;
check+=0XFE;
}
else
{
check=0;
rev_counter=0;
}
break;
case 2:if(recieve_data==0x68)
{
rev_counter++;
//PORTA=0XFB;
check+=0X68;
}
else
{
check=0;
rev_counter=0;
}
break;
case 3: rev_lenth=recieve_data;if(rev_lenth==0x1A){rev_counter++;check+=0X1A;}break;
default:{
if(rev_counter>=4)
{
data_counter++;
if(data_counter<=rev_lenth)
{
data_rev=recieve_data;
rev_counter++;
check+=data_rev;
}
else
{
if (data_counter==rev_lenth+1)
{
//PORTA=0XEF; //第5个灯亮
if(check==recieve_data)
{
//PORTA=0XDF; //第6个灯亮
rev_counter++;
check=0;
}
else
{
rev_counter=0;
check=0;
recieve_data=0;
}
}
if (data_counter==rev_lenth+2)
{
//PORTA=0XBF; //第7个灯亮
if (recieve_data==0xAA)
{
//PORTA=0X7F; //全部正确,最后一个灯亮
sign.bit1=1; //置成功接收标志位
}
rev_counter=0;
check=0;
recieve_data=0;
data_counter=0;
}
}
}
}
}
}
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{
switch (send_step)
{
case 1:send_step=2;UDR=0x4B;PORTB |=0x02;PORTB &=~0x04;break;
case 2:send_step=3;break;//send_step=2;UDR=nm_24c02;send_counter++;if(send_counter>=rev_lenth){send_step=3;}break;
case 3:send_step=0;sign.bit1=0; sign.bit0=0;break;
default:break;
}
//character has been transmitted
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
//timer0_init();
//uart0_init();
MCUCR = 0x00;
GICR= 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialised
}
//*************************************************************************
// 24C02部分
//*************************************************************************
void delay_1ms()
{
unsigned int delay_1;
for(delay_1=0;delay_1<1571;delay_1++)
;
}
void delay(unsigned int n)
{
unsigned int delay_2=0;
for(delay_2=0;delay_2<n;delay_2++)
{
delay_1ms();
}
}
//**************************************************************************
void delay_1us()
{
asm("nop");
asm("nop");
asm("nop");
}
void delayus(unsigned int m)
{
unsigned int delay_3=0;
for(delay_3=0;delay_3<m;delay_3++)
delay_1us();
}
//*******************************************************************************
//24c02测试区
//*******************************************************************************
void i2c_start()
{
//C2402_SDA=1; /*发送起始条件的数据信号*/
PORTA|=0X02;
delayus(10); /*起始条件建立时间大于4.7us,延时*/
//C2402_SCL=1;
PORTA|=0X01;
delayus(10); /*起始条件建立时间大于4.7us,延时*/
//C2402_SDA=0; /*发送起始信号*/
PORTA&=~0X02;
delayus(10); /* 起始条件锁定时间大于4μs*/
//C2402_SCL=0; /*钳住I2C总线,准备发送或接收数据 */
PORTA&=~0X01;
delayus(10); /*起始条件建立时间大于4.7us,延时*/
}
//************************************************************
void i2c_stop()
{
//C2402_SDA=0;/*发送结束条件的数据信号*/
PORTA&=~0X02;
delayus(10); /*发送结束条件的时钟信号*/
//C2402_SCL=0;/*结束条件建立时间大于4μs*/
PORTA&=~0X01;
delayus(10);
//C2402_SCL=1;/*发送I2C总线结束信号*/
PORTA|=0X01;
delayus(10);
//C2402_SDA=1;
PORTA|=0X02;
delayus(10);
}
//************************************************************
//************************************************************
//********************************************
void i2c_send()
{
unsigned char count_i2cs;
for(count_i2cs=0;count_i2cs<8;count_i2cs++)
{
if(((i2cs<<count_i2cs)&0x80)==0)
{
//C2402_SDA=0;
PORTA&=~0X02;
}
else
{
//C2402_SDA=1;
PORTA|=0X02;
}
delayus(10);
//C2402_SCL=1;
PORTA|=0X01;
delayus(10);
//C2402_SCL=0;
PORTA&=~0X01;
delayus(10);
}
//C2402_SDA=1;
PORTA|=0X02;
delayus(10);
//C2402_SCL=1;
PORTA|=0X01;
delayus(10);
//************
//PIND=0XFF;
//******************
//while(C2402_SDA==1)
//PORTA&=~0X08;
DDRA&=~0x02;
//delayus(20);
PORTA&=~0X02;
//PORTA|=0X02;
//delayus(20);
while((PINA&0X02)==0X02)
{
;
}
delayus(10); //灯亮,通过
//******************
DDRA|=0X02;
delayus(10);
//******************
//C2402_SCL=0;
PORTA&=~0X01;
delayus(10);
}
//************************************************************
void i2c_send2()
{
unsigned char count_i2cs;
for(count_i2cs=0;count_i2cs<8;count_i2cs++)
{
if(((i2cs<<count_i2cs)&0x80)==0)
{
//C2402_SDA=0;
PORTA&=~0X02;
}
else
{
//C2402_SDA=1;
PORTA|=0X02;
}
delayus(10);
//C2402_SCL=1;
PORTA|=0X01;
delayus(10);
//C2402_SCL=0;
PORTA&=~0X01;
delayus(10);
}
//C2402_SDA=1;
PORTA|=0X02;
delayus(10);
//C2402_SCL=1;
PORTA|=0X01;
delayus(10);
//************
//PIND=0XFF;
//******************
//while(C2402_SDA==1)
//PORTA&=~0X08;
DDRA&=~0x02;
//delayus(20);
PORTA&=~0X02;
while((PINA&0X02)==0X02)
{
;
}
PORTA &=~0XFC; //灯不亮了没有通过
delayus(10);
//******************
DDRA|=0X02;
delayus(10);
//******************
//C2402_SCL=0;
PORTA&=~0X01;
delayus(10);
}
//************************************************************
void i2c_rece()
{
unsigned char count_i2cr;
//C2402_SCL=0;
PORTA&=~0X01;
i2cr=0;
delayus(10);
//C2402_SDA=1;
PORTA|=0X02;
DDRA&=~0x02;
delayus(10);
PORTA|=0X02;
for(count_i2cr=0;count_i2cr<8;count_i2cr++)
{
//C2402_SCL=1;
PORTA|=0X01;
delayus(10);
i2cr=i2cr<<1;
//if(C2402_SDA==1)
//************
//******************
if((PINA&0X02)==0X02)
{
i2cr=i2cr+1;
}
delayus(10);
//******************
//DDRD|=0X02;
//******************
//C2402_SCL=0;
PORTA&=~0X01;
delayus(10);
}
DDRA|=0x02;
delayus(10);
}
//************************************************************
//
//*********************************************************
void i2c_read(void)
{
unsigned char count_read=0;
i2c_start();
i2cs=0xa0;
i2c_send2();
delayus(10);
i2cs=0x30;
i2c_send2();
i2c_start();
i2cs=0xa1;
i2c_send2();
delayus(10);
i2c_rece();
mydata=i2cr; //0x30里的内容读到NM_LENGRH
i2c_stop();
delayus(10);
}
void i2c_write(void)
{
unsignedcharcount_wirte,count_write1;
i2c_start();
i2cs=0xa0;
i2c_send();
delayus(10);
i2cs=0x30;
i2c_send();
delayus(10);
i2cs=rev_lenth;
i2c_send();
delayus(10);
i2c_stop();
delayus(10);
}
//**************************************************************************
void main(void)
{
init_devices();
//PORTA=0X00;
delay_1us(50);
//**************
data_rev=0x00;
data_rev=0x01;
data_rev=0x02;
data_rev=0x03;
data_rev=0x04;
data_rev=0x05;
data_rev=0x06;
data_rev=0x07;
rev_lenth=0x08;
//***************
//insert your functional code here...
i2c_write();
PORTB |=0x04;
PORTB &=~0x02;
i2c_read();
if(mydata==0x08)
{
PORTA&=~0XFC;
}
} PORTA&=~0XFC是点亮几个灯.我用来试我的程序有没有死机用的.同时也用来检验我写进2402的数对不对 马老师帮帮忙吧。我是个菜鸟,别打击我的积极性。我快崩溃了。 马老师,请您帮忙指点一下把!!! 马老师救命啊!!!指点一下即可!! 马老师救命啊!!!指点一下即可!! 这不是几句话能讲清的,你在网上找点例程参考吧,还是有2-3个的。
我的教材大约10月出版,那里面有对24C256操作的例子,介绍了4种实现方法,有使用I/O模拟的,有使用CVAVR提供的函数的(也是I/O模拟的),有采用硬件TWI实现的等。不过可能时间上等不及了。
页:
[1]