MSP430非模拟IIC总线控制程序

发布者:keiss2018最新更新时间:2015-04-13 来源: eechina关键字:MSP430  非模拟IIC  总线控制程序 手机看文章 扫描二维码
随时随地手机看文章
对于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
#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_AckPolling();
    //写入数据
    EEPROM_ByteWrite(0x0002,0x56);
    //等待写操作完成
    EEPROM_AckPolling();
    //写入数据
    EEPROM_ByteWrite(0x0003,0x78);
    //等待写操作完成
    EEPROM_AckPolling();  
    //写入数据
    EEPROM_ByteWrite(0x0004,0x9A);
    //等待写操作完成
    EEPROM_AckPolling();
    //写入数据
    EEPROM_ByteWrite(0x0005,0xBC);
    //等待写操作完成
    EEPROM_AckPolling();         

    //读出数据,随机读
    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();
}
[page]
IIC.C

#include
#include "IIC.h"

#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();
    //主(Master)模式
    U0CTL |= MST;
    //接收1个字节的数据
    I2CNDAT = 1;  
    //清除中断标志
    I2CIFG &= ~ARDYIFG;
    //开始接收,产生重新起始和停止条件
    I2CTCTL |= I2CSTT + I2CSTP;
    //等待传输完成
    while ((~I2CIFG)&ARDYIFG) ;
    //返回数据
    return I2CBuffer[0];
}

unsigned char EEPROM_RandomRead(unsigned char nAddr)
{
    //等待I2C模块完成所有操作
    while (I2CDCTL&I2CBUSY);
    //设置地址
    I2CBuffer[0] = nAddr;
    //设置缓冲区指针
    tx_count = 0;
    //写操作初始化
    I2CWriteInit();
    //传输数据长度
    //1个控制字节和一个地址数据
    I2CNDAT = 1;
    //清除中断标志
    I2CIFG &= ~ARDYIFG;
    //起始条件产生
    I2CTCTL |= I2CSTT;
    //等待传输完成
    while ((~I2CIFG)&ARDYIFG);
    //读操作初始化
    I2CReadInit();
    //接收一个字节的数据
    I2CNDAT = 1;
    //清除中断标志
    I2CIFG &= ~ARDYIFG;
    //开始接收,产生重新起始和停止条件
    I2CTCTL |= I2CSTT + I2CSTP;  
    //等待传输完成
    while ((~I2CIFG)&ARDYIFG);
    //返回数据
    return I2CBuffer[0];
}

void EEPROM_AckPolling(void)
{
    unsigned int count;
    //等待I2C模块完成所有操作
    while (I2CDCTL&I2CBUSY);
  
    count=0;
    //清除I2CEN位
    U0CTL &= ~I2CEN;
    I2CTCTL |= I2CRM;  
    //使能I2C模块
    U0CTL |= I2CEN;
    //设置NACKIFG标志
    I2CIFG = NACKIFG;
    while (NACKIFG & I2CIFG)
    {
        //清除中断标志
        I2CIFG=0x00;
        //主(Master)模式
        U0CTL |= MST;
        //设置传输模式
        I2CTCTL |= I2CTRX;
        //产生起始条件
        I2CTCTL |= I2CSTT;
       
        //等待I2CSTT被清除
        while (I2CTCTL & I2CSTT) ;
        //产生停止条件
        I2CTCTL |= I2CSTP;
        //等待停止条件复位
        while (I2CDCTL & I2CBUSY) ;
        count = count + 1;
    }
   
    //清除I2CEN位
    U0CTL &= ~I2CEN;
    I2CTCTL &= ~I2CRM;
    //使能I2C
    U0CTL |= I2CEN;

    return;
}
[page]
#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中断
            break;
        }
        case I2CIV_OA:
        {
            //自己地址中断
            break;
        }
        case I2CIV_ARDY:
        {
            //访问准备好中断
            break;
        }
        case I2CIV_RXRDY:
        {
            //接收准备好中断
            I2CBuffer[0]=I2CDRB;  
            break;
        }
        case I2CIV_TXRDY:
        {
            //发送准备好中断
            I2CDRB = I2CBuffer[tx_count];
            tx_count = tx_count - 1;
            if (tx_count < 0)
            {
                //禁止发送中断
                I2CIE &= ~TXRDYIE;
            }
            break;
        }             
        case I2CIV_GC:
        {
            //一般调用中断
            break;
        }
        case I2CIV_STT:
        {
            //起始条件中断
            break;
        }
    }
}
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  非模拟IIC  总线控制程序 引用地址:MSP430非模拟IIC总线控制程序

上一篇:MSP430-低功耗事件驱动工作模式介绍
下一篇:MSP430F149 定时器

推荐阅读最新更新时间:2024-03-16 13:58

基于MSP430单片机的行驶车辆检测器的设计
利用环形线圈、MSP430F1121A单片机与输出接口,组成低功耗行驶车辆检测系统,并能根据用户预先设定的灵敏度、工作方式、输出方式进行车辆检测与信号输出。 还应用软件动态刷新基准的方法提高了检测的可靠性和准确性。实验表明:该系统具有结构简单、功耗低、调节方便等优点。 引言 近年来,车辆检测器作为交通信息采集的重要前端部分,越来越受到业内人士的关注。鉴于公路交通现代化管理和城市交通现代化管理的发展需要,对于行驶车辆的动态检测技术——车辆检测器的研制在国内外均已引起较大重视。车辆检测器以机动车辆为检测目标,检测车辆的通过或存在状况,其作用是为智能交通控制系统提供足够的信息以便进行最优的控制。 目
[单片机]
MSP430单片机GPIO编程入门教程
在本教程中,我们将一起学习MSP430单片机GPIO的编程方法。本文也适用于Launchpad开发板上使用的MSP430x2xx器件,如MSP430G2553、MSP430G2231等。MSP430单片机上的大多数引脚被分组为最多8个端口, P1到P8。每个端口都是8位宽,并有8个相关的I / O引脚。这些引脚直接映射到相应的端口寄存器,因此可以独立操作I / O引脚。只有端口P1和P2中的引脚支持中断。 此外,每个I / O引脚还具有可配置的上拉和下拉电阻。 每个端口都有一组相关的寄存器,用来操作各个引脚。 位映射和端口分组如下所示: 注意:在编程指南/数据手册中使用的引脚的命令约定是’Px.y’,其中’x’对应的是端口号(
[单片机]
<font color='red'>MSP430</font>单片机GPIO编程入门教程
基于CCS工程MSP430串口升级(三)
一、前文 第一次接触MSP430的芯片,第一次使用CCS开发环境,花了将近一个星期的时间,才把MSP430串口升级做出来。 同样分成BOOT(引导程序)、APP(主程序)、上位机(PC端工具),三个部分来讲解。 二、正文 折腾这个功能的时候,遇到了很多问题,现在来一一描述 C和汇编语言混合编程 C语言嵌入汇编语言是asm(“xxx”);,这样一开始编译一直不过。 然后几经百度谷歌后,发现在xxx前面加上制表符t,asm( xxx );,编译就过了。 IAR没有这个问题,CCS就这样。看来CCS编译器还有待改进。 汇编语言,#和&傻傻分不清 mov #0xEFFE,PC和mov &0xEFFE,PC 一开始搞不清楚,啥区
[单片机]
基于CCS工程<font color='red'>MSP430</font>串口升级(三)
MSP430f5529-GPIO简介
理论上来说,在不进行端口功能复用的情况下,每一个端口都能用作普通GPIO口用。其中P1和P2端口可以用作外部中断端口。其余的端口作用可以参考开发板自带的端口功能图。 这里介绍外部中断和普通作用GPIO口寄存器和配置。 430f5529使用的是宏定义的引脚名称。 这里用P1口做例子: 1.P1IN 可以读取当前P1端口某引脚上的信号值,用于读取电平信号,比如检测按键输入,通过读取P1IN 的值判断按键是否按下,如果按下了检测到的都是低电平,返回的就是0,反之1。 用法: if (P1IN & BIT0),此为读取P1.0引脚上电平信号 2.P1OUT 可
[单片机]
<font color='red'>MSP430</font>f5529-GPIO简介
基于msp430单片机定时器的使用方法解析
通过计算设置周期。 #include void main( void ) { // Stop watchdog timer to prevent TIme out reset WDTCTL = WDTPW + WDTHOLD; //WDTCTL = 0X5A80;关狗 CCTL0 = CCIE; //使能CCR0中断 CCR0 = 4095; //设置周期为0.5s TACTL = TASSEL_2 + ID_2 + MC_1; //时钟源的选择,分频,模式 P2DIR = 0XFF; // P2OUT = 0XFF; _EINT(); LPM0; } #pragma vector = TIMERA0_VECTOR __inter
[单片机]
基于<font color='red'>msp430</font>单片机定时器的使用方法解析
入门MSP430FR6989之按键 第四章
新建一个工程,将程序改成如下 #include msp430.h #define uint8 unsigned char #define uint16 unsigned int uint8 key_data(void)//读取按键是否被按下 { uint8 key_value=0; if((P1IN&BIT1) == 0) { __delay_cycles(10000);//延时防抖动 if((P1IN&BIT1) == 0) { key_value=1; while((P1IN&BIT1) == 0); } } return key_value; }
[单片机]
基于MAX5945的以太网供电设备
MSP430F148是美国TI公司推出的超低功耗混合信号控制器MSP430系列中的Flash型单片机。它具有16位RISC结构,CPU中的16个寄存器和常数发生器使MSP430微控制器能达到最高的代码效率;灵活的时钟源可以使器件达到最低的功耗;数字控制的振荡器(DCO)可使器件从低功耗模式迅速唤醒,在6 μs之内激活到活跃的工作方式。将它应用于以太网供电设备中,可方便地实现对以太网供电电源管理芯片的控制,也可以使用户方便地通过终端监控程序对以太网供电设备进行监控。 1 IEEE802.3af标准简介 IEEE802.3af标准定义了一种允许通过以太网在传输数据的同时输送48 V直流电源的方法。它将以太网供电(Power o
[单片机]
基于MAX5945的以太网供电设备
基于MSP430心肺听诊技能训练系统的设计
摘要:基于MSP430心肺听诊技能训练系统针对现代医学模拟教学的发展,改变过去用射频和特制听诊器来模仿心肺听诊过程,在操作上更逼真临床真实环境。以低功耗的MSP430为核心,并在模型人上安装27个专用设备来模拟人体的共118种心肺听诊的疾病声音。另外还可以用遥控器设置模型人的疾病类型,通过听诊器来识别模型人位置点发出的声音来辨别疾病。再现临床医学的工作场景,为学习者提供一个无风险的学习临床知识和技能的条件与环境。此外还添加了上位机教学系统,上住机根据收到的位置信号来控制上位机软件界面的显示,可以显示听诊的位置、声音特点、与呼吸的关系以及声音的波形信息,还可以外接扬声器放大播放所听到的心肺声音,达到医学教学的目的。 关键词:MS
[工业控制]
基于<font color='red'>MSP430</font>心肺听诊技能训练系统的设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved