完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用的是msp430F5529的LaunchPad,对EEPROM进行读写。开发环境是CCS6.0,430的寄存器和库函数混合编写。个人觉得ti给的例子不够好,之前都是用库函数写msp430F5529的,硬件IIC调了半天调不好。为了直观看到寄存器配置,430的寄存器和库函数混合编写。 下面上逻辑分析仪的图 图为IIC读写时序
图为IIC写时序 图为IIC读时序 读有个小问题,最后总会多读一位。 是由必须在接受最后一个数据之前发送停止和NACK,而我把这个发送放在中断里的(放我的发送函数里会出现一些问题),数据进缓冲器在进中断服务程序前,所以会多读一个。但是不影响,我后面已做处理,不管最后一个字符。 /****************************************************************IIC_device.c*********************************************************************************************************/ #include "IIC_device.h" #include "Delay.h" extern unsigned char RXByteCtr; extern unsigned char TXByteCtr; extern unsigned char TxData[10]; extern unsigned char RxBuf[10]; void iic_init(uint8_t SLAVE_ADDRESS) { //Assign I2C pins to USCI_B0 P3.0 IIC_SDA P3.1 IIC_SCL P3SEL |= 0x03; UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 |= UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 |= UCSSEL_2 + UCSWRST; // Use SMCLK UCB0BR0 = 240; // fSCL = SMCLK/240 = 100kHz UCB0BR1 = 0; UCB0I2CSA = SLAVE_ADDRESS; // Slave Address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation } void iic_WriteMode(void) { UCB0CTL1 |= UCTR; USCI_B_I2C_clearInterrupt(USCI_B0_BASE,USCI_B_I2C_TRANSMIT_INTERRUPT); UCB0IE &= ~UCRXIE; // Disable RX interrupt UCB0IE |= UCTXIE; // Enable TX interrupt } void iic_ReadMode(void) { UCB0CTL1 &=~ UCTR; USCI_B_I2C_clearInterrupt(USCI_B0_BASE,USCI_B_I2C_RECEIVE_INTERRUPT); UCB0IE &= ~UCTXIE; // Disable TX interrupt UCB0IE |= UCRXIE; // Enable RX interrupt } void iic_writebyte(uint8_t reg_address,uint8_t write_number,uint8_t *data_to_write) { uint8_t i=0; while(UCB0STAT & UCBBUSY); iic_WriteMode(); TxData[write_number]=reg_address; for(i=write_number;i>0;i--) { TxData[i-1]= *data_to_write++; } TXByteCtr=write_number+1; // Load TX byte counter UCB0CTL1 |= UCTXSTT; // I2C TX, start condition while (UCB0CTL1 & UCTXSTP); } void iic_readbyte(uint8_t reg_address,uint8_t read_number) { while(UCB0STAT & UCBBUSY); iic_WriteMode(); TxData[0]=reg_address; TXByteCtr=1; // Load TX byte counter UCB0CTL1 |= UCTXSTT; // I2C TX, start condition while (UCB0CTL1 & UCTXSTP); Delay_us(200); iic_ReadMode(); RXByteCtr=read_number; UCB0CTL1 |= UCTXSTT; while (USCI_B_I2C_getInterruptStatus(USCI_B0_BASE,USCI_B_I2C_RECEIVE_INTERRUPT)); while (UCB0CTL1 & UCTXSTP); } /****************************************************************IIC_device.h*********************************************************************************************************/ #ifndef IIC_DEVICE_H_ #define IIC_DEVICE_H_ #include "MSP430F5529_conf.h" void iic_init(uint8_t SLAVE_ADDRESS); void iic_WriteMode(void); void iic_ReadMode(void); void iic_writebyte(uint8_t reg_address,uint8_t write_number,uint8_t *data_to_write); void iic_readbyte(uint8_t reg_address,uint8_t read_number); #endif /* IIC_DEVICE_H_ */ /*******************************************************************main.c*********************************************************************************************************/ /************************************************************************ * @file main.c * @author Mr.Blue * @version V1.0 * @date 2015-6-16 * @brief This file provides functions to manage the functionalities * of the IIC * @verbatim ************************************************************************/ /******************************INCLUDE**********************************/ #include "MSP430F5529_conf.h" #include "Delay.h" #include "IIC_device.h" /******************************DEFINE***********************************/ #define UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ 24000 //Target frequency for MCLK in kHz #define UCS_MCLK_FLLREF_RATIO 6 //MCLK/FLLRef Ratio #define UCS_XT1_TIMEOUT 50000 //Desired Timeout for XT1 initialization #define UCS_XT2_TIMEOUT 50000 //Desired Timeout for XT2 initialization #define IIC_SLAVE_ADDRESS 0X50 void UCS_init(); void GPIO_init(); /*****************************VARIABLE**********************************/ u16 status; //Variable to store status of Oscillator fault flags unsigned char TXByteCtr=0,RXByteCtr=0; unsigned char TxData[10]={0}; unsigned char RxBuf[10]={0}; uint8_t data_address=2; uint8_t data_to_write[10]={'A','B','C','D','E','F','G','H','I','J'}; uint8_t data_to_read[10]={0}; /*******************************MAIN************************************/ int main(void) { u8 j=0; WDT_A_hold(WDT_A_BASE); UCS_init(); GPIO_init(); iic_init(IIC_SLAVE_ADDRESS); iic_writebyte(data_address,4,data_to_write); Delay_ms(2); //EEPROM在读写切换时需要一定延时,亲测读写为4个时至少2MS,读写10个时至少5MS iic_readbyte(data_address,4); while(1) { for(j=0;j<=9;j++) { data_to_read[j]=RxBuf[9-j]; } GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0); Delay_ms(500); } } void UCS_init() { //Set VCore = 3 for 25MHz clock PMM_setVCore(PMM_CORE_LEVEL_3 ); UCS_setExternalClockSource(32768,4000000); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN4); GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5,GPIO_PIN5); UCS_turnOnLFXT1WithTimeout(UCS_XT1_DRIVE_0,UCS_XCAP_3,UCS_XT1_TIMEOUT); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN2); GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5,GPIO_PIN3); UCS_turnOnXT2WithTimeout(UCS_XT2_DRIVE_4MHZ_8MHZ,UCS_XT2_TIMEOUT); //Select XT1 as ACLK source UCS_initClockSignal(UCS_ACLK,UCS_XT1CLK_SELECT,UCS_CLOCK_DIVIDER_1); //Select XT2 as FLL reference UCS_initClockSignal(UCS_FLLREF,UCS_XT2CLK_SELECT,UCS_CLOCK_DIVIDER_1); //Set Ratio and Desired MCLK Frequency and initialize DCO UCS_initFLLSettle(UCS_MCLK_DESIRED_FREQUENCY_IN_KHZ,UCS_MCLK_FLLREF_RATIO); //Select DCO as SMCLK source UCS_initClockSignal(UCS_SMCLK,UCS_DCOCLK_SELECT,UCS_CLOCK_DIVIDER_1); // Enable global oscillator fault flag SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); SFR_enableInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); // Enable global interrupt __bis_SR_register(GIE); } void GPIO_init() { GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0); GPIO_setAsOutputPin(GPIO_PORT_P4,GPIO_PIN7); } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=UNMI_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(UNMI_VECTOR))) #endif void NMI_ISR(void) { do { // If it still can't clear the oscillator fault flags after the timeout, // trap and wait here. status = UCS_clearAllOscFlagsWithTimeout(1000); } while(status != 0); } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_B0_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(USCI_B0_VECTOR))) #endif void USCI_B0_ISR(void) { { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG if (RXByteCtr) { RXByteCtr--; RxBuf[RXByteCtr] = UCB0RXBUF; if(RXByteCtr==0) { UCB0CTL1 |= UCTXSTP+UCTXNACK; //必须在接受最后一个数据之前发送停止和NACK } UCB0CTL1 &=~UCTXNACK; } else { USCI_B_I2C_clearInterrupt(USCI_B0_BASE,USCI_B_I2C_RECEIVE_INTERRUPT); } break; case 12: if (TXByteCtr) // Check TX byte counter { TXByteCtr--; UCB0TXBUF = TxData[TXByteCtr]; // Load TX buffer } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag } break; // Vector 12: TXIFG default: break; } } } /****************************************************************Delay.h*********************************************************************************************************/ // 4M晶振 #ifndef __DELAY_H_ #define __DELAY_H_ #define CPU_F ((double)1000000) #define Delay_us(x) __delay_cycles((long)(24*CPU_F*(double)x/1000000.0)) #define Delay_ms(x) __delay_cycles((long)(24*CPU_F*(double)x/1000.0)) #endif /* DELAY_H_ */ |
|
相关推荐
|
|
本帖最后由 Mr.Bluyee 于 2017-1-31 10:57 编辑
|
|
|
|
|
|
|
|
|
|
|
|
顶个。。。。。。。。。。。。。。
|
|
|
|
|
|
非常感谢,一直在调DA用IIC。
|
|
|
|
|
|
感谢.很有用........
|
|
|
|
|
|
这个很有用!!!!
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
3055个成员聚集在这个小组
加入小组2978 浏览 1 评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3703 浏览 2 评论
请问怎么把下面51单片机的代码改成msp430 g2 pocket的代码,还有改下时间变成30秒
2366 浏览 1 评论
4832 浏览 1 评论
2594 浏览 1 评论
1490浏览 3评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3704浏览 2评论
2980浏览 1评论
1687浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 22:25 , Processed in 1.716334 second(s), Total 80, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号