其他重要外设
目录
- SPI通信
- I2C通信
- CAN通信
- DMA传输
- 看门狗定时器
- EEPROM模拟
SPI通信
F280049C有2个SPI模块(SPIA, SPIB),支持主从模式。
SPI特性
- 速度: 最高25 Mbps
- 数据位: 1-16位可配置
- 模式: 主机/从机模式
- FIFO: 16级发送和接收FIFO
- 时钟极性: 可配置CPOL和CPHA
基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include "driverlib.h" #include "device.h"
void SPIA_Init_Master(void) { GPIO_setPinConfig(GPIO_58_SPIA_CLK); GPIO_setPinConfig(GPIO_59_SPIA_STE); GPIO_setPinConfig(GPIO_60_SPIA_SIMO); GPIO_setPinConfig(GPIO_61_SPIA_SOMI);
SPI_disableModule(SPIA_BASE);
SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0, SPI_MODE_MASTER, 1000000, 16);
SPI_enableFIFO(SPIA_BASE); SPI_setFIFOInterruptLevel(SPIA_BASE, SPI_FIFO_TX0, SPI_FIFO_RX1);
SPI_enableModule(SPIA_BASE); }
uint16_t SPIA_Transfer(uint16_t data) { SPI_writeDataBlockingNonFIFO(SPIA_BASE, data);
return SPI_readDataBlockingNonFIFO(SPIA_BASE); }
|
SPI读写示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| uint16_t SPI_ReadRegister(uint8_t reg_addr) { uint16_t tx_data = (0x80 | reg_addr) << 8; uint16_t rx_data = SPIA_Transfer(tx_data); return rx_data & 0xFF; }
void SPI_WriteRegister(uint8_t reg_addr, uint8_t value) { uint16_t tx_data = (reg_addr << 8) | value; SPIA_Transfer(tx_data); }
|
I2C通信
F280049C有2个I2C模块(I2CA, I2CB),支持标准和快速模式。
I2C特性
- 速度: 标准模式100kHz,快速模式400kHz
- 地址: 7位或10位地址
- 模式: 主机/从机模式
- FIFO: 4级发送和接收FIFO
基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include "driverlib.h" #include "device.h"
void I2CA_Init_Master(void) { GPIO_setPinConfig(GPIO_32_I2CA_SDA); GPIO_setPinConfig(GPIO_33_I2CA_SCL); GPIO_setPadConfig(32, GPIO_PIN_TYPE_PULLUP); GPIO_setPadConfig(33, GPIO_PIN_TYPE_PULLUP); GPIO_setQualificationMode(32, GPIO_QUAL_ASYNC); GPIO_setQualificationMode(33, GPIO_QUAL_ASYNC);
I2C_disableModule(I2CA_BASE); I2C_initMaster(I2CA_BASE, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_50); I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE); I2C_setSlaveAddress(I2CA_BASE, 0x50); I2C_disableLoopback(I2CA_BASE); I2C_setBitCount(I2CA_BASE, I2C_BITCOUNT_8); I2C_setDataCount(I2CA_BASE, 1); I2C_setAddressMode(I2CA_BASE, I2C_ADDR_MODE_7BITS); I2C_enableFIFO(I2CA_BASE); I2C_setFIFOInterruptLevel(I2CA_BASE, I2C_FIFO_TX0, I2C_FIFO_RX1); I2C_setEmulationMode(I2CA_BASE, I2C_EMULATION_FREE_RUN); I2C_enableModule(I2CA_BASE); }
void I2C_WriteData(uint16_t slave_addr, uint8_t reg_addr, uint8_t data) { while(I2C_isBusBusy(I2CA_BASE));
I2C_setSlaveAddress(I2CA_BASE, slave_addr);
I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE); I2C_setDataCount(I2CA_BASE, 2);
I2C_sendStartCondition(I2CA_BASE);
I2C_putData(I2CA_BASE, reg_addr);
while(I2C_getStopConditionStatus(I2CA_BASE) == false);
I2C_putData(I2CA_BASE, data);
I2C_sendStopCondition(I2CA_BASE);
while(I2C_getStopConditionStatus(I2CA_BASE) == false); }
uint8_t I2C_ReadData(uint16_t slave_addr, uint8_t reg_addr) { while(I2C_isBusBusy(I2CA_BASE));
I2C_setSlaveAddress(I2CA_BASE, slave_addr); I2C_setConfig(I2CA_BASE, I2C_MASTER_SEND_MODE); I2C_setDataCount(I2CA_BASE, 1); I2C_sendStartCondition(I2CA_BASE); I2C_putData(I2CA_BASE, reg_addr); while(I2C_getStopConditionStatus(I2CA_BASE) == false);
I2C_setConfig(I2CA_BASE, I2C_MASTER_RECEIVE_MODE); I2C_setDataCount(I2CA_BASE, 1); I2C_sendStartCondition(I2CA_BASE); I2C_sendStopCondition(I2CA_BASE); while(I2C_getStopConditionStatus(I2CA_BASE) == false);
return I2C_getData(I2CA_BASE); }
|
CAN通信
F280049C有2个CAN模块(CANA, CANB),支持CAN 2.0B协议。
CAN特性
- 速度: 最高1 Mbps
- 邮箱: 32个邮箱
- 标识符: 标准11位或扩展29位
- 过滤: 可配置接收过滤器
基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include "driverlib.h" #include "device.h"
void CANA_Init(void) { GPIO_setPinConfig(GPIO_30_CANA_RX); GPIO_setPinConfig(GPIO_31_CANA_TX);
CAN_initModule(CANA_BASE);
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);
CAN_setupMessageObject(CANA_BASE, 1, 0x123, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, 8);
CAN_setupMessageObject(CANA_BASE, 2, 0x456, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_NO_FLAGS, 8);
CAN_startModule(CANA_BASE); }
void CAN_SendMessage(uint32_t msg_id, uint8_t *data, uint16_t len) { CAN_sendMessage(CANA_BASE, 1, len, data); }
bool CAN_ReceiveMessage(uint8_t *data, uint16_t *len) { if(CAN_readMessage(CANA_BASE, 2, data)) { *len = 8; return true; } return false; }
|
DMA传输
DMA可以在不占用CPU的情况下传输数据。
DMA特性
- 通道数: 6个DMA通道
- 触发源: ADC, SPI, SCI等
- 传输模式: 单次、突发、连续
基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include "driverlib.h" #include "device.h"
uint16_t adc_buffer[128];
void DMA_Init_ADC(void) { DMA_initController();
DMA_configAddresses(DMA_CH1_BASE, (uint16_t *)&AdcaResultRegs.ADCRESULT0, adc_buffer);
DMA_configBurst(DMA_CH1_BASE, 1, 1, 1);
DMA_configTransfer(DMA_CH1_BASE, 128, 1, 1);
DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_ADCA1, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT);
DMA_enableTrigger(DMA_CH1_BASE); DMA_startChannel(DMA_CH1_BASE); }
|
看门狗定时器
看门狗定时器用于检测系统故障并复位系统。
看门狗特性
- 超时时间: 可配置
- 复位模式: 系统复位或中断
- 窗口模式: 可选
基本配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include "driverlib.h" #include "device.h"
void Watchdog_Init(void) { SysCtl_disableWatchdog();
}
void Watchdog_Feed(void) { SysCtl_serviceWatchdog(); }
|
EEPROM模拟
F280049C没有内置EEPROM,可以使用Flash模拟。
Flash特性
- 扇区大小: 4KB
- 编程: 按字编程
- 擦除: 按扇区擦除
基本操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include "driverlib.h" #include "device.h"
#define FLASH_SECTOR_ADDR 0x88000
void Flash_EraseSector(uint32_t sector_addr) { EALLOW; Flash_eraseBank(sector_addr, FLASH_BANK0); EDIS; }
void Flash_WriteData(uint32_t addr, uint16_t *data, uint16_t len) { EALLOW; Flash_program(addr, data, len, FLASH_BANK0); EDIS; }
void Flash_ReadData(uint32_t addr, uint16_t *data, uint16_t len) { for(uint16_t i = 0; i < len; i++) { data[i] = *(uint16_t *)(addr + i * 2); } }
|
综合示例:数据采集系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| #include "driverlib.h" #include "device.h"
#define SAMPLE_RATE 1000 #define BUFFER_SIZE 128
uint16_t adc_buffer[BUFFER_SIZE]; volatile uint16_t buffer_index = 0; volatile bool buffer_full = false;
__interrupt void adcA1ISR(void) { adc_buffer[buffer_index++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
if(buffer_index >= BUFFER_SIZE) { buffer_index = 0; buffer_full = true; }
ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1); Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1); }
void System_Init(void) { Device_init(); Device_initGPIO();
Interrupt_initModule(); Interrupt_initVectorTable();
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(EPWM1_BASE, 100000); EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO); EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0); ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED); ADC_enableConverter(ADCA_BASE); DEVICE_DELAY_US(1000);
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, 15); ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0); ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1); ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER1);
Interrupt_register(INT_ADCA1, &adcA1ISR); Interrupt_enable(INT_ADCA1);
GPIO_setPinConfig(GPIO_28_SCIA_TX); GPIO_setPinConfig(GPIO_29_SCIA_RX); SCI_setConfig(SCIA_BASE, DEVICE_LSPCLK_FREQ, 115200, (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE)); SCI_enableFIFO(SCIA_BASE); SCI_enableModule(SCIA_BASE); SCI_resetChannels(SCIA_BASE);
EINT; ERTM; }
void SendDataToPC(void) { for(uint16_t i = 0; i < BUFFER_SIZE; i++) { SCI_writeCharBlockingFIFO(SCIA_BASE, (adc_buffer[i] >> 8) & 0xFF); SCI_writeCharBlockingFIFO(SCIA_BASE, adc_buffer[i] & 0xFF); } }
void main(void) { System_Init();
while(1) { if(buffer_full) { buffer_full = false; SendDataToPC(); } } }
|
学习建议
- 循序渐进: 先掌握基础外设(GPIO、TIMER、UART),再学习高级外设
- 实践为主: 多动手编写代码,运行示例程序
- 参考例程: C2000Ware提供了丰富的示例代码
- 使用SysConfig: 图形化配置可以快速上手
- 阅读手册: Technical Reference Manual是最权威的参考资料
参考资料
- TMS320F28004x Technical Reference Manual
- C2000Ware DriverLib API Guide
- C2000Ware Example Code
- TI E2E Forum: https://e2e.ti.com/
- C2000 Academy: 在线培训课程
总结
通过本系列教程,你已经学习了:
- ✓ GPIO配置和使用
- ✓ CPU定时器
- ✓ UART串口通信
- ✓ ePWM输出
- ✓ ADC采集
- ✓ SPI、I2C、CAN等通信接口
- ✓ DMA传输
- ✓ 看门狗和Flash操作
现在你已经具备了开发F280049C应用的基础知识。继续深入学习,结合实际项目,你将能够开发出更复杂的嵌入式系统!
祝学习顺利!🚀