AVR 主从通信
来源:互联网 发布:虚拟机mac os x 10.11 编辑:程序博客网 时间:2024/06/07 06:00
/************************************
* 功 能:用TWI主从通信 *
* 建立日期:2008年11月04日 *
* 设 计 者: *
* 版 本: *
* 修改日期:2012-9-6 *
* 主控芯片:ATmega16 *
* 时钟频率:外部晶体7.3728MHz *
* 编 译 器:ICCAVR6.31A *
************************************/
#include "config.h"
uint8 IIC_transmit[TXNUM];
uint8 IIC_receive [RXNUM];
#if TWI_MOD == 1 //从机模式
void twi_master_init(void)
{
PORTC |= (1<<SCL)|(1<<SDA);
DDRC &= ~((1<<SCL)|(1<<SDA));
TWCR= 0x00;
TWSR= 0x00; //set prescale
TWBR= (F_CPU/F_IIC_SCL - 16)>>1;//250; //set bit rate
/*
CPU Clock frequency
SCL frequency = --------------------
16 + 2(TWBR) * 4
*/
TWAR= 0x00; //set slave address
TWCR= 0x04; //enable twi
}
//总线上起动开始条件
void i2c_start(void)
{
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))); //等待START 信号成功发送
}
//把一个字节数据输入器件, 返回TWI状态
//发送地址,r_w:1为读,0为写
uint8 i2c_write_addr(uint8 addr,uint8 r_w)
{
if(r_w)
{
TWDR = addr|r_w; //RW 为1:读操作
}
else
{
TWDR = addr & 0xFE; // RW 为0: 写操作
}
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
_NOP();
return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
}
//把一个字节数据输入器件, 返回TWI状态
//发送数据
uint8 i2c_write_data(uint8 data)
{
TWDR = data;
TWCR |= (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));
_NOP();
return(TWSR&0b11111000); //TWSR高五位为I2C工作状态。
}
void i2c_Read_Ack(void)
{
uint8 i=0;
for(i=0; i<100; i++)
{
if((TWSR&0b11111000) == MT_SLA_ACK)
{
_NOP();
break;
}
_NOP();
_NOP();
}
}
//从器件读出一个字节
uint8 i2c_read(void)
{
return(TWDR);
}
//总线上起动停止条件
void i2c_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
//操作步骤: 启动,发送地址,发送数据,关闭总线
void i2c_maste_transt(uint8 addr,uint8 *data,uint8 tx_count)
{
uint8 i=0;
i2c_start();
if(i2c_write_addr(addr<<1, 0)==MT_SLA_ACK) //发送地址成功并收到ACK
{
for(i=0; i<tx_count; i++)
{
i2c_write_data(*data);
data++;
i2c_Read_Ack();
}
}
i2c_stop();
}
//操作步骤,启动,发送地址,读数据,关闭总线
void i2c_maste_read(uint8 addr, uint8 *data,uint8 rx_count)
{
unsigned char i = 0;
unsigned char j = 0;
PORTD |= 0xCC;
DDRD |= 0xCC;
DDRB = 0xFF;
DDRA |= 0xff;
i2c_start();
if(i2c_write_addr(addr<<1, 1)!= MR_SLA_ACK) //发送地址成功并收到ACK
{
return;
}
for(i=0; i<rx_count-1; i++)
{
Twi_Ack();
Twi_WaitForComplete();
*data = TWDR;
data++;
}
Twi_NoAck();
Twi_WaitForComplete();
*data = TWDR;
i2c_stop();
}
#endif
#if TWI_MOD == 0 //从机模式
void twi_slave_init(uint8 addr)
{
PORTC |= (1<<SCL)|(1<<SDA);
DDRC &= ~((1<<SCL)|(1<<SDA));
TWCR = 0x00;
TWSR= 0x00; //set prescale
TWBR= (F_CPU/F_IIC_SCL - 16)>>1;//250; //set bit rate
/*
CPU Clock frequency
SCL frequency = --------------------
16 + 2(TWBR) * 4
*/
TWAR = addr<<1;
TWDR = 0x00;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE)|(1<<TWEA);
}
#pragma interrupt_handler TWI_ISR:18
void TWI_ISR(void)
{
static volatile uint8 transmit_cnt = 0;
static volatile uint8 receive_cnt = 0;
uint8 *p_sr = &IIC_receive[0];
uint8 *p_st = &IIC_receive[0];
//uint8 receive[2]= {2,3};
SREG &= ~0x80;
switch(TWSR&0xf8)
{
case SR_SLA_ACK:
case SR_ARB_LOST_SLA_ACK:
receive_cnt = 0;
transmit_cnt = 0;
Twi_Ack()
break;
case SR_DATA_ACK:
if (receive_cnt < (RXNUM-1))
{
*(p_sr+receive_cnt) = TWDR;
}
else if (receive_cnt == (RXNUM-1))
{
*(p_sr+receive_cnt) = TWDR;
receive_ready = 1;
}
receive_cnt++; ;
Twi_Ack()
break;
case SR_STOP: // 0xA0:从机工作时收到STOP或RESTART
Twi_Ack()
break;
case ST_SLA_ACK: // 0XA8:从机发送地址应答
transmit_cnt = 0;
TWDR = *(p_st);
transmit_cnt++;
Twi_Ack()
break;
case ST_DATA_ACK: // 0XB8:从机发送数据应答
if (transmit_cnt < TXNUM)
{
TWDR = *(p_st+transmit_cnt);
}
transmit_cnt++;
Twi_Ack()
break;
case ST_DATA_NACK:
//transmit_ready = 1;
transmit_cnt = 0;
Twi_Ack()
break;
case BUS_ERROR:
case NO_INFO:
TWI_RESUME();
break;
}
SREG |= 0x80;
}
#endif
- AVR 主从通信
- AVR主从通信
- 基于NRF24L01的AVR双机通信
- CPLD 与AVR通信 PWM控制程序
- AVR单片机ATMega16的UART通信总结
- STM32_SPI主从通信
- AVR
- nrf51822---主从通信(1)
- nrf51822 --- 主从通信(2)
- nrf51822-主从通信分析1
- nrf51822-主从通信分析2
- AVR 单片机串口和网口的通信
- 使用串口通信实现AVR的ISP下载
- RS485多机通信程序(终结版AVR)
- redis主从复制+2种原理图+主从复制通信过程+主从复制案例+设置主从复制通信密码
- MSP430F249—SPI主从机通信
- STM32F407和STM32F051主从I2C通信方法
- nrf51822---主从一体通信(3)
- Tornado基于方法的url分发器
- 在Myeclipse中使用Extjs的示例工程
- Qt 使用vs调试的方法
- Struts2基于注解的Action配置
- 诺基亚时代终结?新手机仍不能吸引投资
- AVR 主从通信
- Android如何运行真机在eclipse上调试应用? .
- hdu 1711 Number Sequence (KMP - 初步)
- struts2中<s:doubleselect/>标签的使用心得<>
- 正则表达式学习笔记(4) 贪婪、惰性和支配量词
- Android在listview添加checkbox实现单选多选操作问题
- 使用生成器遍历目录
- CSS样式大全
- 一个老程序员分析程序员为什么会跳槽