您现在的位置: 主页 > MCU > MSP430 > MSP430非模拟IIC总线控制程序
本文所属标签:
为本文创立个标签吧:

MSP430非模拟IIC总线控制程序

来源:网络整理 网络用户发布,如有版权联系网管删除 2018-06-29 

对于MSP430的学习经历一个从痛苦到对430很有感情的转变.当然开始学习的时候那是相当恼火.网上也没有什么很多的相关资料.就算有资料也是给不全.参考与学习都不很方便.经过多方面的努力和找书再到对程序的仔细读,感到非模拟的总线带来的方便还是很多的. 下面就是程序和流程图:

IIC.h

void Init_IIC(void);

void EEPROM_ByteWrite(unsigned char nAddr,unsigned char nVal);

unsigned char EEPROM_RandomRead(unsigned char nAddr);

unsigned char EEPROM_CurrentAddressRead(void);

void EEPROM_AckPolling(void);

void Init_CLK(void);

void Init_IIC_Port(void);

Main.C

/*******************************************

IIC for AT24c16 OR AT24CXXX 系列

只要控制好IICRM IICSTP IICSTT 其硬件会自动完成

SCL SDA的一系列时序 只要注意各个发送与接收的控制标志位.

******************************************/

#include <MSP430x16x.h>

#include "IIC.h"

volatile unsigned char Data[6];

void main(void)

{

//volatile unsigned char Data[6];

//停止看门狗

WDTCTL = WDTPW+WDTHOLD;

//初始化端口

Init_IIC_Port();

//初始化时钟

Init_CLK();

//I2C初始化

Init_IIC(); //置传输方式及控制方式

//打开中断

_EINT();

//写入数据

EEPROM_ByteWrite(0x0000,0x12);

//等待写操作完成

EEPROM_AckPolling();

EEPROM_ByteWrite(0x0001,0x34);

EEPROM_ByteWrite(0x0002,0x56);

EEPROM_ByteWrite(0x0003,0x78);

EEPROM_ByteWrite(0x0004,0x9A);

EEPROM_ByteWrite(0x0005,0xBC);

//读出数据,随机读

Data[0] = EEPROM_RandomRead(0x0000); //地址自动加1

//读出数据,当前地址读

Data[1] = EEPROM_CurrentAddressRead();

Data[2] = EEPROM_CurrentAddressRead();

Data[3] = EEPROM_CurrentAddressRead();

Data[4] = EEPROM_CurrentAddressRead();

Data[5] = EEPROM_CurrentAddressRead();

}

IIC.C

#define SLAVEADDR 0x50;

int tx_count;

int rx_count;

unsigned char I2CBuffer[3];

void Init_IIC(void)

//将P3.1和P3.3设置为I2C管脚

P3SEL = 0x0A;

//设置P3.1和P3.3管脚的方向

P3DIR &= ~0x0A;

//选择为I2C模式

U0CTL |= I2C + SYNC;

//禁止I2C模块

U0CTL &= ~I2CEN;

//设置I2C为7位地址模式,不使用DMA,

//字节模式,时钟源为SMCLK,

//设置成传输模式

I2CTCTL = I2CTRX + I2CSSEL_2;

//定义从器件地址

I2CSA = SLAVEADDR;

//设置本身的地址

I2COA = 0x01A5;

//I2C时钟为SMCLK / 160

I2CPSC = 159;

//SCL 高电平为:5 *I2C 时钟

I2CSCLH = 0x03;

//SCL 低电平为:5 *I2C 时钟

I2CSCLL = 0x03;

//I2C 模块有效

U0CTL |= I2CEN;

tx_count = 0;

rx_count = 0;

void I2CWriteInit(void) //对于AT24CXXX的写操作是置成主模式并置位中断使能.

//主(Master)模式

U0CTL |= MST;

//传输模式,R/W 为:0

I2CTCTL |= I2CTRX;

//清除中断标志

I2CIFG &= ~TXRDYIFG;

//发送中断使能

I2CIE = TXRDYIE;

void I2CReadInit(void)

//接收模式,R/W 为:1

I2CTCTL &= ~I2CTRX;

//接收中断使能

I2CIE = RXRDYIE;

void EEPROM_ByteWrite(unsigned char nAddr, unsigned char nVal)

//等待I2C模块完成所有操作 //在选定的地址写入数据.

while (I2CDCTL&I2CBUSY) ;

//设置地址数据

I2CBuffer[1] = nAddr;

//设置数据

I2CBuffer[0] = nVal;

//设置缓冲区指针

tx_count = 1;

//写数据初始化

I2CWriteInit(); //设置为主模式

//发送数据的长度

//1个控制字节,2个数据字节

I2CNDAT = 2;

//开始和停止条件产生

//开始I2C通信

I2CTCTL |= I2CSTT+I2CSTP;

return;

unsigned char EEPROM_CurrentAddressRead(void)

//等待I2C模块完成所有操作

while (I2CDCTL&I2CBUSY);

//读操作的初始化

I2CReadInit();

//接收1个字节的数据

I2CNDAT = 1;

I2CIFG &= ~ARDYIFG;

//开始接收,产生重新起始和停止条件

I2CTCTL |= I2CSTT + I2CSTP;

//等待传输完成

while ((~I2CIFG)&ARDYIFG) ;

//返回数据

return I2CBuffer[0];

unsigned char EEPROM_RandomRead(unsigned char nAddr)

//设置地址

I2CBuffer[0] = nAddr;

//写操作初始化

I2CWriteInit();

//传输数据长度

//1个控制字节和一个地址数据

//起始条件产生

I2CTCTL |= I2CSTT;

while ((~I2CIFG)&ARDYIFG);

//读操作初始化

//接收一个字节的数据

void EEPROM_AckPolling(void)

unsigned int count;

count=0;

//清除I2CEN位

I2CTCTL |= I2CRM;

//使能I2C模块

//设置NACKIFG标志

I2CIFG = NACKIFG;

while (NACKIFG & I2CIFG)

I2CIFG=0x00;

//设置传输模式

//产生起始条件

//等待I2CSTT被清除

while (I2CTCTL & I2CSTT) ;

//产生停止条件

I2CTCTL |= I2CSTP;

//等待停止条件复位

while (I2CDCTL & I2CBUSY) ;

count = count + 1;

I2CTCTL &= ~I2CRM;

//使能I2C

#if __VER__ < 200

interrupt [USART0TX_VECTOR] void ISR_I2C(void)

#else

#pragma vector=USART0TX_VECTOR

__interrupt void ISR_I2C(void)

#endif //上面的程序其实只要编写 :

//#pragma vector=USART0TX_VECTOR __interrupt void ISR_I2C(void)就行.

switch (I2CIV)

case I2CIV_AL:

//仲裁中断

break;

case I2CIV_NACK:

//NACK中断

case I2CIV_OA:

//自己地址中断

case I2CIV_ARDY:

//访问准备好中断

case I2CIV_RXRDY:

//接收准备好中断

I2CBuffer[0]=I2CDRB;

case I2CIV_TXRDY:

//发送准备好中断

I2CDRB = I2CBuffer[tx_count];

tx_count = tx_count - 1;

if (tx_count < 0)

//禁止发送中断

I2CIE &= ~TXRDYIE;

case I2CIV_GC:

//一般调用中断

case I2CIV_STT:

//起始条件中断

void Init_IIC_Port(void)

//初始化端口寄存器 与IIC口无关的PX口关闭以便于对编写系统板的综合程序.

//P1DIR = 0xFF;

//P2DIR = 0xFF;

P3DIR = 0xF5;

//P4DIR = 0xFF;

P5DIR = 0x7F;

//P6DIR = 0xFF;

//P4OUT = 0X11;

//P5OUT &= 0XF0;

P3SEL|=BIT1+BIT3; //在这里如果设置成

void Init_CLK(void)

unsigned int i;

//将寄存器的内容清零

//XT2震荡器开启

//LFTX1工作在低频模式

//ACLK的分频因子为1

BCSCTL1 = 0X00;

do

// 清除OSCFault标志

IFG1 &= ~OFIFG;

for (i = 0x20; i > 0; i--);

while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1

//open XT2, LFTX2 选择低频率

BCSCTL1 &= ~(XT2OFF + XTS); //BCSCTL1=0X00 功能一样

//DCO Rsel=7(Freq=3200k/25摄氏度)

BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;

BCSCTL1 |= 0x07;

//MCLK的时钟源为TX2CLK,分频因子为1

BCSCTL2 += SELM1;

//SMCLK的时钟源为TX2CLK,分频因子为1

BCSCTL2 += SELS;

//对于系统时钟的选择关系到整个程序运行稳定性.

看到很多卖开发板的人将IIC硬件写上去后再去搞个模拟的IIC总线程序. 感觉到有点说不出的感觉. 其实430的IIC不是专用来外扩展FLASH的,而是用来和一些特殊的电路连接,实现功能. 对于MSP430147~149 15X 16X 的芯片内部有48~60K的Flash了还有必要来个模拟的IIC总线时序么.装个UCOS都可以了.开发板要做的事情就是如何做好非模拟IIC程序的设计.更不是为了和C1搞比拼抢占市场.

上面的程序是经过MSP430F1611的测试.程序的大部分来自<MSP430系列16位超低功耗单片机原理与应用>上,曾想自己从新开发定义一个,但想到网络上没有这个程序的完整版.我就修改了其中的几个地方.一方面便于自己查看并复习也适于网络上的朋友来讨论交流.



              查看评论 回复



嵌入式交流网主页 > MCU > MSP430 > MSP430非模拟IIC总线控制程序
 设置 数据 中断

"MSP430非模拟IIC总线控制程序"的相关文章

网站地图

围观()