快捷搜索:  汽车  科技

msp430单片机有多少条内核指令(用MSP430的IO模拟I2C协议读写EEPROM)

msp430单片机有多少条内核指令(用MSP430的IO模拟I2C协议读写EEPROM)以下为实现IO模拟I2C协议的源程序/************************************************************************************************** MCU型号: MSP430F6736A 编译平台: IAR for MSP430 6.40.1 实验项目: IO模拟I2C协议 **************************************************************************************************/ #include "msp430.h" #include "msp430f6736a.h" #include "stdio.h"

I2C接口是单片机开发中很常用的一种接口,比如一些EEPROM,ADC,DAC等器件都通过I2C接口对芯片进行控制,或读写里面的数据。

I2C协议比较简单,容易实现,可以通过MCU的IO口来模拟实现,避免操作芯片里面的I2C控制器。

本文以MSP430为例,写了一个完整的IO模拟I2C的代码。当使用其他类型的MCU时,也可以轻松的将其移植过去。

msp430单片机有多少条内核指令(用MSP430的IO模拟I2C协议读写EEPROM)(1)

原理图

以下为实现IO模拟I2C协议的源程序

/************************************************************************************************** MCU型号: MSP430F6736A 编译平台: IAR for MSP430 6.40.1 实验项目: IO模拟I2C协议 **************************************************************************************************/ #include "msp430.h" #include "msp430f6736a.h" #include "stdio.h" #include "stdlib.h" #include "string.h" #include "math.h" #define uchar unsigned char #define uint unsigned int //--------------------------------- // 初始化MCU //--------------------------------- void Mcu_Init(void) { //--------------------------------- // 初始化系统时钟 //--------------------------------- WDTCTL = WDTPW WDTHOLD; // 禁止看门狗 __bic_SR_register(GIE); // 禁止所有中断 // 初始化XT1 并使其正常工作 UCSCTL6 &= ~(XT1OFF XT1BYPASS XTS); UCSCTL6 |= XT1DRIVE_3; UCSCTL6 |= XCAP_3; do { UCSCTL7 &= ~XT1LFOFFG; } while (UCSCTL7 & XT1LFOFFG); // XT1CLK作为DCO输入 UCSCTL3 = SELREF__XT1CLK FLLREFDIV__1; // 禁止 FLL 控制 __bis_SR_register(SCG0); // DCO=31 MOD=0 UCSCTL0 = 0x1f00; // DCO 范围: 23.7MHz - 54.1MHz UCSCTL1 = DCORSEL_5; // fDCO分频系数D = 2 N = 374 // fDCOCLK = D * (N 1) * FLLRef = 2 * (374 1) * 32768 = 24576000 Hz UCSCTL2 = FLLD__2 | 374; // 允许 FLL 控制 __bic_SR_register(SCG0); __delay_cycles(384000); do { UCSCTL7 &= ~(DCOFFG); } while (UCSCTL7 & DCOFFG); // ACLK=XT1CLK SMCLK=DCOCLK MCLK=DCOCLK UCSCTL4 = SELA__XT1CLK SELS__DCOCLK SELM__DCOCLK; //---------------------------------------------------------- // P2功能【外接信号】 功能 方向 初始值 // P2.1 | PM_UCB0SIMO | PM_UCB0SDA | COM7 |【I2C_SDA】 0[I/O] 1[O] [1] // P2.0 | PM_UCB0SOMI | PM_UCB0SCL | COM6 |【I2C_SCL】 0[I/O] 1[O] [1] //---------------------------------------------------------- P2SEL = 0; P2DIR = 0xff; P2OUT = 0xff; P2REN |= 0x02; } //--------------------------------- // I2C协议 //--------------------------------- #define SETB_I2C_SCL (P2OUT|=BIT0) #define CLR_I2C_SCL (P2OUT&=~bit0) #define SETB_I2C_SDA (P2OUT|=BIT1) #define CLR_I2C_SDA (P2OUT&=~BIT1) #define I2C_SDA_IS_SET (P2IN&BIT1) #define I2C_SDA_IS_CLR ((P2IN&BIT1)==0) #define I2C_SDA_INPUT (P2DIR&=~BIT1) #define I2C_SDA_OUTPUT (P2DIR|=BIT1) uchar I2C_Byte; void Start_I2C(void) { SETB_I2C_SDA; SETB_I2C_SCL; CLR_I2C_SDA; CLR_I2C_SCL; } void Stop_I2C(void) { CLR_I2C_SDA; SETB_I2C_SCL; SETB_I2C_SDA; } void Send_ACK(void) { CLR_I2C_SDA; SETB_I2C_SCL; CLR_I2C_SCL; } void Send_NACK(void) { SETB_I2C_SDA; SETB_I2C_SCL; CLR_I2C_SCL; } void To_I2C(void) { uchar i bitset; bitset = 0x80; for (i=0; i<8; i ) { if (bitset & I2C_Byte) SETB_I2C_SDA; else CLR_I2C_SDA; bitset /= 2; SETB_I2C_SCL; CLR_I2C_SCL; } // 将I2C_SDA切换到输入模式 I2C_SDA_INPUT; Send_NACK(); // 将I2C_SDA切换到输出模式 I2C_SDA_OUTPUT; } void From_I2C(void) { uchar i bitset; // 将I2C_SDA切换到输入模式 I2C_SDA_INPUT; SETB_I2C_SDA; bitset = 0x80; I2C_Byte = 0x00; for (i=0; i<8; i ) { SETB_I2C_SCL; if (I2C_SDA_IS_SET) I2C_Byte |= bitset; CLR_I2C_SCL; bitset /= 2; } // 将I2C_SDA切换到输出模式 I2C_SDA_OUTPUT; } //--------------------------------- // 写EEPROM(24CL04) //--------------------------------- void WriteEE(uint EEAddr uchar *RamAddr uint Len) { uint i; if (Len == 0) return; Start_I2C(); I2C_Byte = (uchar)((EEAddr & 0xff00) >> 7); I2C_Byte &= 0x02; I2C_Byte = 0xa0; To_I2C(); I2C_Byte = (uchar)(EEAddr & 0x00ff); To_I2C(); for (i=0; i<Len; i ) { I2C_Byte = RamAddr[i]; To_I2C(); } Stop_I2C(); } //--------------------------------- // 读EEPROM(24CL04) //--------------------------------- void ReadEE(uint EEAddr uchar *RamAddr uint Len) { uint i; if (Len == 0) return; Start_I2C(); I2C_Byte = (uchar)((EEAddr & 0xff00) >> 7); I2C_Byte &= 0x02; I2C_Byte = 0xa0; To_I2C(); I2C_Byte = (uchar)(EEAddr & 0x00ff); To_I2C(); Start_I2C(); I2C_Byte = (uchar)((EEAddr & 0xff00) >> 7); I2C_Byte &= 0x02; I2C_Byte = 0xa1; To_I2C(); for (i=0; i<Len; i ) { From_I2C(); RamAddr[i] = I2C_Byte; if (i != (Len-1)) { Send_ACK(); } } Send_NACK(); Stop_I2C(); } //--------------------------------- // 主流程 //--------------------------------- void main(void) { uchar i ctmp sbuf[10]; // 初始化MCU Mcu_Init(); // 初始化LCD Lcd_Init(); Disp_RomString(Msg_WriteEE LINE1 NORMAL); Disp_RomString(Msg_ReadEE LINE4 NORMAL); i = 0; while(1) { ctmp = i; WriteEE(0 &ctmp 1); sprintf((char *)sbuf "d" ctmp); Disp_RamString8x16(sbuf LINE1 11 NORMAL); DELAY_400ms; ctmp = 0; ReadEE(0 &ctmp 1); sprintf((char *)sbuf "d" ctmp); Disp_RamString8x16(sbuf LINE4 11 NORMAL); DELAY_400ms; i ; } }

视频演示内容:先向EEPROM的地址0写入一个字节,然后从此地址读出,看是否与写入的内容一致

猜您喜欢: