其他重要外设

目录

  1. SPI通信
  2. I2C通信
  3. CAN通信
  4. DMA传输
  5. 看门狗定时器
  6. 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引脚
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
SPI_disableModule(SPIA_BASE);

// 配置SPI为主机模式
SPI_setConfig(SPIA_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,
SPI_MODE_MASTER, 1000000, 16); // 1MHz, 16位数据

// 使能FIFO
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
// 读取SPI设备寄存器
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;
}

// 写入SPI设备寄存器
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引脚
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
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引脚
GPIO_setPinConfig(GPIO_30_CANA_RX);
GPIO_setPinConfig(GPIO_31_CANA_TX);

// 初始化CAN
CAN_initModule(CANA_BASE);

// 设置波特率(500kbps)
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 16);

// 配置邮箱1为发送
CAN_setupMessageObject(CANA_BASE, 1, 0x123,
CAN_MSG_FRAME_STD,
CAN_MSG_OBJ_TYPE_TX,
0, CAN_MSG_OBJ_NO_FLAGS, 8);

// 配置邮箱2为接收
CAN_setupMessageObject(CANA_BASE, 2, 0x456,
CAN_MSG_FRAME_STD,
CAN_MSG_OBJ_TYPE_RX,
0, CAN_MSG_OBJ_NO_FLAGS, 8);

// 启动CAN
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; // CAN数据长度
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
DMA_initController();

// 配置DMA通道1
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通道
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();

// 或者配置看门狗
// SysCtl_setWatchdogPredivider(SYSCTL_WD_PREDIV_512);
// SysCtl_setWatchdogMode(SYSCTL_WD_MODE_RESET);
// SysCtl_enableWatchdog();
}

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 // Flash扇区地址

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 // 1kHz采样率
#define BUFFER_SIZE 128

// 数据缓冲区
uint16_t adc_buffer[BUFFER_SIZE];
volatile uint16_t buffer_index = 0;
volatile bool buffer_full = false;

// ADC中断
__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触发ADC
EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(EPWM1_BASE, 100000); // 1kHz
EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);

// 配置ADC
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);

// 配置UART
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)
{
// 发送数据到PC
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();
}
}
}

学习建议

  1. 循序渐进: 先掌握基础外设(GPIO、TIMER、UART),再学习高级外设
  2. 实践为主: 多动手编写代码,运行示例程序
  3. 参考例程: C2000Ware提供了丰富的示例代码
  4. 使用SysConfig: 图形化配置可以快速上手
  5. 阅读手册: Technical Reference Manual是最权威的参考资料

参考资料

  • TMS320F28004x Technical Reference Manual
  • C2000Ware DriverLib API Guide
  • C2000Ware Example Code
  • TI E2E Forum: https://e2e.ti.com/
  • C2000 Academy: 在线培训课程

总结

通过本系列教程,你已经学习了:

  1. ✓ GPIO配置和使用
  2. ✓ CPU定时器
  3. ✓ UART串口通信
  4. ✓ ePWM输出
  5. ✓ ADC采集
  6. ✓ SPI、I2C、CAN等通信接口
  7. ✓ DMA传输
  8. ✓ 看门狗和Flash操作

现在你已经具备了开发F280049C应用的基础知识。继续深入学习,结合实际项目,你将能够开发出更复杂的嵌入式系统!

祝学习顺利!🚀