平台:Code Composer Studio 10.4.0
MSP430F5529 LaunchPad™ Development Kit
(MSP‑EXP430F5529LP)
I2C驱动代码
P3.0为SDA,P3.1为SCL
MSP430F5529_I2C.c
#include "driverlib.h"
#define I2C_USCI_BASE USCI_B0_BASE
#define I2C_USCI_VECTOR USCI_B0_VECTOR
#define I2C_USCI_IV UCB0IV
#define I2C_BUF_LENGTH 32
static char i2c_buf[I2C_BUF_LENGTH];
static uint8_t i2c_buf_len = 0;
static uint8_t i2c_buf_cur = 0;
static uint8_t *i2c_rx_buf = 0;
static uint8_t i2c_rx_buf_len = 0;
void Init_I2C_GPIO(void)
{
/* Select I2C function for I2C_SDA & I2C_SCL */
GPIO_setAsPeripheralModuleFunctionOutputPin(
GPIO_PORT_P3,
GPIO_PIN0 | GPIO_PIN1);
}
/***************************************************************************//**
* @brief Configures I2C
* @param none
* @return none
******************************************************************************/
void I2C_init(uint8_t slaveAddress)
{
/* I2C Master Configuration Parameter */
USCI_B_I2C_initMasterParam i2cConfig =
{
USCI_B_I2C_CLOCKSOURCE_SMCLK,
UCS_getSMCLK(),
USCI_B_I2C_SET_DATA_RATE_400KBPS
};
/* Initialize USCI_B0 and I2C Master to communicate with slave devices*/
USCI_B_I2C_initMaster(I2C_USCI_BASE, &i2cConfig);
/* Enable I2C Module to start operations */
USCI_B_I2C_enable(I2C_USCI_BASE);
// Specify slave address
USCI_B_I2C_setSlaveAddress(I2C_USCI_BASE, slaveAddress);
USCI_B_I2C_clearInterrupt(I2C_USCI_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);
USCI_B_I2C_enableInterrupt(I2C_USCI_BASE, USCI_B_I2C_RECEIVE_INTERRUPT);
USCI_B_I2C_clearInterrupt(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
USCI_B_I2C_enableInterrupt(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_INTERRUPT);
return;
}
/* write a byte to specific register, cannot called in interrupt context */
void writeByte(uint8_t byte)
{
while (USCI_B_I2C_isBusBusy(I2C_USCI_BASE));
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_MODE);
// Initiate start and send first character
i2c_buf[0] = byte;
i2c_buf_cur = 1;
i2c_buf_len = 1;
USCI_B_I2C_masterSendMultiByteStart(I2C_USCI_BASE, i2c_buf[0]);
// wait for end
__bis_SR_register(GIE + LPM0_bits);
__no_operation();
}
/* write a word to specific register, cannot called in interrupt context */
void writeWord(uint16_t word)
{
while (USCI_B_I2C_isBusBusy(I2C_USCI_BASE));
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_MODE);
// Initiate start and send first character
i2c_buf[0] = word >> 8;
i2c_buf[1] = (uint8_t)word;
i2c_buf_cur = 1;
i2c_buf_len = 2;
USCI_B_I2C_masterSendMultiByteStart(I2C_USCI_BASE, i2c_buf[0]);
// wait for end
__bis_SR_register(GIE + LPM0_bits);
__no_operation();
}
///* set/clear some bit to specific register, cannot called in interrupt context */
//void writeBit(uint8_t regAddr, uint8_t bitNum, uint8_t data)
//{
// uint8_t b = 0;
// readByte(regAddr, &b);
// delay_ms(2);
// b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));
// writeByte(regAddr, b);
//}
/* read some byte from specific register, cannot called in interrupt context */
void readByte(uint8_t RegAddr, uint8_t* b)
{
while (USCI_B_I2C_isBusBusy(I2C_USCI_BASE));
// send address
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_MODE);
i2c_buf_cur = 1;
i2c_buf_len = 1;
USCI_B_I2C_masterSendSingleByte(I2C_USCI_BASE, RegAddr);
// receive
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_RECEIVE_MODE);
i2c_rx_buf = b;
i2c_rx_buf_len = 1;
USCI_B_I2C_masterReceiveSingleStart(I2C_USCI_BASE);
// wait for end
__bis_SR_register(GIE + LPM0_bits);
__no_operation();
}
void readBytes(uint8_t RegAddr, uint8_t length, uint8_t* data)
{
while (USCI_B_I2C_isBusBusy(I2C_USCI_BASE));
// send address
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_TRANSMIT_MODE);
i2c_buf_cur = 1;
i2c_buf_len = 1;
USCI_B_I2C_masterSendSingleByte(I2C_USCI_BASE, RegAddr);
// receive
USCI_B_I2C_setMode(I2C_USCI_BASE, USCI_B_I2C_RECEIVE_MODE);
i2c_rx_buf = data;
i2c_rx_buf_len = length;
USCI_B_I2C_masterReceiveMultiByteStart(I2C_USCI_BASE);
// wait for end
__bis_SR_register(GIE + LPM0_bits);
__no_operation();
}
#pragma vector = I2C_USCI_VECTOR
__interrupt void USCI_B0_ISR(void)
{
switch (__even_in_range(I2C_USCI_IV, 12))
{
case USCI_I2C_UCTXIFG:
if (i2c_buf_cur < i2c_buf_len)
{
USCI_B_I2C_masterSendMultiByteNext( I2C_USCI_BASE, i2c_buf[i2c_buf_cur]);
i2c_buf_cur++;
}
else
{
USCI_B_I2C_masterSendMultiByteStop(I2C_USCI_BASE);
//Clear master interrupt status
USCI_B_I2C_clearInterrupt(I2C_USCI_BASE,
USCI_B_I2C_TRANSMIT_INTERRUPT);
__bic_SR_register_on_exit(LPM0_bits);
}
break;
case USCI_I2C_UCRXIFG:
i2c_rx_buf_len--;
if(i2c_rx_buf_len)
{
if(i2c_rx_buf_len== 1)
{
//Initiate end of reception -> Receive byte with NAK
*i2c_rx_buf++ = USCI_B_I2C_masterReceiveMultiByteFinish( I2C_USCI_BASE);
}
else
{
//Keep receiving one byte at a time
*i2c_rx_buf++ = USCI_B_I2C_masterReceiveMultiByteNext( I2C_USCI_BASE);
}
}
else
{
//Receive last byte
*i2c_rx_buf= USCI_B_I2C_masterReceiveMultiByteNext(I2C_USCI_BASE);
__bic_SR_register_on_exit(LPM0_bits);
}
break;
}
}
MSP430F5529_I2C.h
#ifndef MSP430F5529_I2C_H_
#define MSP430F5529_I2C_H_
void Init_I2C_GPIO(void);
void I2C_init(uint8_t slaveAddress);
void writeByte(uint8_t byte);
void writeWord(uint16_t word);
void readByte(uint8_t RegAddr, uint8_t* b);
void readBytes(uint8_t RegAddr, uint8_t length, uint8_t* data);
#endif /* MSP430F5529_I2C_H_ */
OLED初始化及测试
#include "driverlib.h"
#include "MSP430F5529_I2C.h"
#include "./OLED/OLED.h"
#define MCLK_IN_HZ 25000000
#define delay_us(x) __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x) __delay_cycles((MCLK_IN_HZ/1000*(x)))
void SystemClock_Init(void)
{
PMM_setVCore(PMM_CORE_LEVEL_3); //高主频工作需要较高的核心电压
//XT1引脚复用
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);
//起振XT1
UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);
//XT2引脚复用
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);
GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);
//起振XT2
UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);
//XT2作为FLL参考时钟,先8分频,再50倍频 4MHz / 8 * 50 = 25MHz
UCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);
UCS_initFLLSettle(25000, 50);
//XT1作为ACLK时钟源 = 32768Hz
UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);
//DCOCLK作为MCLK时钟源 = 25MHz
UCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
//DCOCLK作为SMCLK时钟源 = 25MHz
UCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
//设置外部时钟源的频率,使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值
UCS_setExternalClockSource(32768, 4000000);
}
int main(void)
{
WDT_A_hold(WDT_A_BASE);
SystemClock_Init();
Init_I2C_GPIO();
I2C_init(OLED_ADDRESS >> 1);
__bis_SR_register(GIE);
OLED_Init();
OLED_Clear();
OLED_Display_On();
上一篇:MSP432P401R TI Drivers 库函数学习笔记(一)导入工程模板
下一篇:MSP430F5529 DriverLib 库函数学习笔记(十五)SFR 模块
推荐阅读最新更新时间:2024-11-19 17:53