📄 scm2481_iic.txt
字号:
/********************************Copyright (c)**********************************
**
**
*******************************************************************************/
/*******************************************************************************
**------------------------------单片机2481 IIC通信------------------------------
** 文件名: main.c
** 最后修改时间:
** 最后修改版本:
** 版本改进:
**------------------------------------------------------------------------------
** 创建者:
** 建立时间: 2007-11-26
** 版 本: 1.0
** Descriptions: 单片机2481同单片机2012、TMS320VC5509A(DSP)通信
*******************************************************************************/
/*******************************************************************************
** 功 能 :使用IIC模块同5509A通信信令,以及从单片机2012获取时间信息。
** 说 明 :通信波特率100kbps,简单累加校验
** 全局变量 :IIC_flag_master_receive; IIC_flag_master_send;
** IIC_flag_receive_succeed; Flag_ReReceive;
** IIC_slave; Rx_Num ;
** data_Tx[]; data_Rx[];
** 中 断 : USCIAB0TX_ISR(); USCIAB0RX_ISR();
** IIC_ISR();
**
*******************************************************************************/
/*相关包含文件*/
#include "msp430x24x1.h"
/*全局变量*/
int IIC_flag_master_receive = 0; //请求主接受单片机2012时间信息标志位
int IIC_flag_master_send = 0; //请求主发送数据给DSP标志位
int IIC_slave = 1; //工作模式(1:从模式 ;0:主模式)
int IIC_flag_receive_succeed = 0; //接收成功标志位(替代Flag_received = 0)
int Flag_ReReceive;
//int Check_Sum,IIC_Tx_Num = 5;
//int i = 1,w(用delay替代);
volatile int Rx_Num = 0; //接收数据计数
volatile int IIC_Tx_Num = 5; //发送个数
unsigned char data_Tx[9] = // 发送数组
{
0x11,
0x22,
0x33,
0x44,
0xaa
};
unsigned char data_Rx[7] = //接收数组
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
/*
********************************************************************************
** 函数名称 :def_slave()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :寄存器设置,使2481工作在从模式
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
**中断情况: 无
********************************************************************************
*/
void def_slave( void )
{
UCB0CTL1 |= UCSWRST; // I2C设置使能
UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C主模式,工作在同步模式
UCB0I2COA = 0x55; // 主地址0x55h
UCB0CTL1 &= ~UCSWRST; // 清I2C设置使能位
UCB0I2CIE |= UCSTPIE + UCSTTIE; // 开开始和结束中断使能
IE2 |= UCB0RXIE+UCB0TXIE; // 接收和发送中断使能
Rx_Num = 0;
}
/*
********************************************************************************
** 函数名称 :def_master()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :寄存器设置,使2481工作在主模式
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
**中断情况: 无
********************************************************************************
*/
void def_master( void )
{
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
if( IIC_flag_master_send == 1)
UCB0I2CSA = 0x20; // DSP地址:0x20h
else
UCB0I2CSA = 0x048; // 单片机2012地址:0x48h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0TXIE+UCB0RXIE; // Enable TX and RX interrupt
}
/*
********************************************************************************
** 函数名称 :Master_Tx_IIC_ISR()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :主发送数据给DSP并主接收DSP的校验数据,判断通信是否成功。
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
**中断情况: 无
********************************************************************************
*/
void Master_Tx_IIC_ISR(void)
{
if( IIC_Tx_Num > 0 ){ // 还有多于一个数据等待发送?
UCB0TXBUF = data_Tx[5 - IIC_Tx_Num]; // 发送数据
IIC_Tx_Num--;
}
else{
if( IIC_Tx_Num == 0){
UCB0TXBUF = data_Tx[5-IIC_Tx_Num]; // 发最后一个数据
IIC_Tx_Num = -1;
UCB0CTL1 &= ~UCTR; // 将主机设为接收模式
UCB0CTL1 |= UCTXSTT; // 发送起始位
IFG2 &= ~UCB0TXIFG; // 清发送标志位
Rx_Num = 2; //接收数据个数
}
else{
Rx_Num--;
if( Rx_Num ){
data_Tx[5] = UCB0RXBUF; // 将数据从接收移位寄存器存放到存储数组
UCB0CTL1 |= UCTXSTP;
}
else{
data_Tx[5] = UCB0RXBUF;
if( data_Tx[5] == data_Tx[4] ){ //数据正确?
IIC_flag_master_send = 0;
P1IE &= 0xFE; //关P1.0中断
}
}
}
}
}
/*
********************************************************************************
** 函数名称 :Slave_Rx_IIC_ISR()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :从接收DSP信令和校验数据,判断接收数据正确性,然后从发送数据给DSP
** 调试说明 :无
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
**中断情况: 无
********************************************************************************
*/
void Slave_Rx_IIC_ISR( void )
{
if( IFG2 & UCB0RXIFG ){
data_Rx[Rx_Num++] = UCB0RXBUF;
if( Rx_Num == 6 ){
data_Rx[6] = ( data_Rx[4] + data_Rx[1] + data_Rx[2] + data_Rx[3] ) & ( 0xff ); // 计算校验和
if( data_Rx[5] == data_Rx[6] ){ //数据正确?
IIC_flag_receive_succeed = 1;
Flag_ReReceive = 0;
P1IE &= 0xFE;
}
}
else
data_Rx[5] = 0xFF;
}
else if( IFG2 & UCB0TXIFG )
UCB0TXBUF = data_Rx[5];
else;
}
/*
********************************************************************************
** 函数名称 :main()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :实现单片机2481与单片机2012以及DSP之间的相互通信
** 调试说明 :在config.h中包含stdio.h
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
**中断情况: 单片机2481需要从单片机2012接收时间信息或者发送数据给DSP,
并且p1.0口接收到上升沿时,开IIC_ISR()中断。
********************************************************************************
*/
void main(void)
{
static int pro_data = 0; //数据处理标志位(1:有数据待处理;0:无数据需处理)
int delay = 0; //延时
WDTCTL = WDTPW + WDTHOLD;
P1IES = 0x01; //中断触发沿:下降沿
P3SEL |= 0x06;
def_slave();
pro_data = ( IIC_flag_master_send ) || ( IIC_flag_master_receive );
if( pro_data )
P1IE = 0x01; //中断使能
__bis_SR_register(GIE); // 开全局中断
/*接收2012数据校验*/
for( delay = 0; delay++; delay <100 ) //延时
{;}
if( Rx_Num == 4 ){
data_Rx[5] = ( data_Rx[0] + data_Rx[1] + data_Rx[2] + data_Rx[3] ) & ( 0xff ); // 计算校验和
if( data_Rx[5] == data_Rx[4] ){ //数据正确?
IIC_flag_receive_succeed = 1;
Flag_ReReceive = 0;
P1IE &= 0xFE;
}
}
else
data_Rx[5] = 0x88;
while(1);
}
/*
********************************************************************************
** 中断函数名称 : USCIAB0TX_ISR()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :主接收单片机2012数据或者主发送数据至DSP
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
** 中断情况: 单片机2481需要从单片机2012接收时间信息或者发送数据给DSP
**
********************************************************************************
*/
#pragma vector = USCIAB0TX_VECTOR //IIC中断
__interrupt void USCIAB0TX_ISR(void)
{
if( IIC_slave == 1 ){
int i = 1;
if( i ){ //置数一次
i = 0;
IIC_flag_receive_succeed = 0;
Flag_ReReceive = 1;
//P1IE |= 0x01; //开P1.0中断,这个中断在调试时应该关掉,因为调试时不能保证几个器件之间的运行同步
}
Slave_Rx_IIC_ISR();
}
else if( IIC_flag_master_send == 1)
Master_Tx_IIC_ISR();
else if( IIC_flag_master_receive == 1 )
data_Rx[Rx_Num++] = UCB0RXBUF;
else ;
}
/*
********************************************************************************
** 函数名称 : USCIAB0RX_ISR()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :清起始和结束标志位中
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
** 中断情况: 无
**
********************************************************************************
*/
#pragma vector = USCIAB0RX_VECTOR
__interrupt void USCIAB0RX_ISR(void)
{
UCB0STAT &= ~( UCSTPIFG + UCSTTIFG ); // 清中断标志位
}
/*
********************************************************************************
** 函数名称 : IIC_ISR()
** 作者:
** 修改时间 :2008-11-26
** 函数功能 :主接收单片机2012数据或者主发送数据至DSP
** 入口参数 :无
** 出口参数 :无
** 版本改进: 无
** 中断情况: 单片机2481需要从单片机2012接收时间信息或者发送数据给DSP,
并且p1.0口接收到上升沿。
**
********************************************************************************
*/
#pragma vector = PORT1_VECTOR
__interrupt void IIC_ISR(void)
{
P1IE &= 0xFE; //关中断 (调试用,程序中删除)
P1IFG &= 0xFE; //清中断标志位
if( IIC_flag_master_send == 1 ){
def_master();
data_Tx[4] = ( data_Tx[0] + data_Tx[1] + data_Tx[2] + data_Tx[3] ) & ( 0xFF ); //计算校验和
while ( UCB0CTL1 & UCTXSTP ); // Ensure stop condition got sent
UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
}
else{
int Cyc_Num = 5; //循环接收次数
Rx_Num = 0;
def_master();
while( Cyc_Num-- ){
while( UCB0CTL1 & UCTXSTP ); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT; // I2C start condition
while( UCB0CTL1 & UCTXSTT ); // Start condition sent?
UCB0CTL1 |= UCTXSTP; // I2C stop condition
__bis_SR_register( GIE ); //开全局中断,这是必须的
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -