赞
踩
外设或通信协议
寄存器编程的例程在C:\ti\c2000\C2000Ware_2_01_00_00\device_support\f28004x,
库函数编程的例程在C:\ti\c2000\C2000Ware_2_01_00_00\driverlib\f28004x\examples。
实验参考的例程库函数版,主要针对ADC和CAN
例程是针对ControlCARD开发的,如果想将其应用到LaunchPad上,自然需要更改引脚映射。具体的代码可以在devices.h中找到。
芯片在上电或复位后会自动使能看门狗,所以初始化函数的第一句是将其关闭。
Register protection is enabled by default at startup. While protected, all writes to protected registers by the CPU
are ignored.
研究三个例子代码
//! This example demonstrates how to blink a LED.
//! If using LaunchPad, select build configuration for LAUNCHXL.
//! This example converts some voltages on ADCA and ADCB based on a software
//! trigger.
//! This example sets up the ePWM to periodically trigger the ADC. The
//! ADC converts the internal connection to the temperature sensor,
//! which is then interpreted as a temperature by calling the
//! ADC_getTemperatureC() function.
//! This example shows the basic setup of CAN in order to transmit and receive
//! messages on the CAN bus. The CAN peripheral is configured to transmit
//! messages with a specific CAN ID. A message is then transmitted once per
//! second, using a simple delay loop for timing. The message that is sent is
//! a 2 byte message that contains an incrementing pattern.
- //led_ex1_blinky.c
- void main(void)
- {
- //设备初始化
- Device_init();
-
- //设备引脚初始化
- Device_initGPIO();
-
- //设备引脚配置
- GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
- GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
-
- //初始化并清除 PIE registers. 关闭 CPU interrupts.
- Interrupt_initModule();
-
- // 初始化 PIE vector table ,指向 the shell Interrupt
- Interrupt_initVectorTable();
-
-
- // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
- EINT;
- ERTM;
-
-
- for(;;)
- {
-
- // Turn on LED
- GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);
-
- // Delay for a bit.
- DEVICE_DELAY_US(500000);
-
- // Turn off LED
-
- GPIO_writePin(DEVICE_GPIO_PIN_LED1, 1);
-
- // Delay for a bit.
- DEVICE_DELAY_US(500000);
- }
- }
- FILE: adc_ex1_soc_software.c
- void main(void)
- {
-
- Device_init();
- Device_initGPIO();
- Interrupt_initModule();
- Interrupt_initVectorTable();
-
- // Set up ADCs, initializing the SOCs to be triggered by software
- initADCs();
- initADCSOCs();
-
- EINT;
- ERTM;
-
- while(1)
- {
- //
- // Convert, wait for completion, and store results
- //
- ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
- ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER1);
- ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER0);
- ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER1);
-
- //
- // Wait for ADCA to complete, then acknowledge flag
- //
- while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false)
- {
- }
- ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
-
- //
- // Wait for ADCB to complete, then acknowledge flag
- //
- while(ADC_getInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1) == false)
- {
- }
- ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);
-
- //
- // Store results
- //
- adcAResult0 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
- adcAResult1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
- adcBResult0 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0);
- adcBResult1 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1);
-
- //
- // Software breakpoint. At this point, conversion results are stored in
- // adcAResult0, adcAResult1, adcBResult0, and adcBResult1.
- //
- // Hit run again to get updated conversions.
- //
- ESTOP0;
- }
- }
- //FILE: adc_ex3_temp_sensor.c
- void main(void)
- {
-
- Device_init();
-
- Device_initGPIO();
-
- Interrupt_initModule();
-
- Interrupt_initVectorTable();
-
- //
- // Interrupts that are used in this example are re-mapped to ISR functions
- // found within this file.
- //
- Interrupt_register(INT_ADCB1, &adcB1ISR);
-
- //
- // Set up the ADC and the ePWM and initialize the SOC
- //
- initADC();
- initEPWM();
- initADCSOC();
-
-
- // Enable the temperature sensor and give it 500 us to power up
- ASysCtl_enableTemperatureSensor();
- DEVICE_DELAY_US(500);
-
- // Enable ADC interrupt
- Interrupt_enable(INT_ADCB1);
-
-
- // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
- EINT;
- ERTM;
-
- // Start ePWM1, enabling SOCA and putting the counter in up-count mode
- EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
- EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);
-
-
- while(1)
- {
- ;
- }
- }
- void main(void)
- {
- uint16_t txMsgData[2], rxMsgData[2];
-
-
- Device_init();
-
- Device_initGPIO();
- GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
- GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
-
- //
- // Initialize the CAN controller
- //
- CAN_initModule(CANA_BASE);
-
- //
- // Set up the CAN bus bit rate to 500kHz
- // Refer to the Driver Library User Guide for information on how to set
- // tighter timing control. Additionally, consult the device data sheet
- // for more information about the CAN module clocking.
- //
- CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 20);
-
-
- Interrupt_initModule();
- Interrupt_initVectorTable();
-
- EINT;
- ERTM;
-
- //
- // Enable CAN test mode with external loopback
- //
- CAN_enableTestMode(CANA_BASE, CAN_TEST_EXL);
-
- //
- // Initialize the transmit message object used for sending CAN messages.
- // Message Object Parameters:
- // Message Object ID Number: 1
- // Message Identifier: 0x1234
- // Message Frame: Standard
- // Message Type: Transmit
- // Message ID Mask: 0x0
- // Message Object Flags: None
- // Message Data Length: 2 Bytes
- //
- CAN_setupMessageObject(CANA_BASE, 1, 0x1234, CAN_MSG_FRAME_STD,
- CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS,
- MSG_DATA_LENGTH);
-
- //
- // Initialize the receive message object used for receiving CAN messages.
- // Message Object Parameters:
- // Message Object ID Number: 2
- // Message Identifier: 0x1234
- // Message Frame: Standard
- // Message Type: Receive
- // Message ID Mask: 0x0
- // Message Object Flags: None
- // Message Data Length: 2 Bytes
- //
- CAN_setupMessageObject(CANA_BASE, 2, 0x1234, CAN_MSG_FRAME_STD,
- CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_NO_FLAGS,
- MSG_DATA_LENGTH);
-
- //
- // Start CAN module operations
- //
- CAN_startModule(CANA_BASE);
-
- //
- // Setup send and receive buffers
- //
- txMsgData[0] = 0x01;
- txMsgData[1] = 0x02;
- *(uint16_t *)rxMsgData = 0;
- //
- // Loop Forever - Send and Receive data continuously
- //
- for(;;)
- {
- //
- // Send CAN message data from message object 1
- //
- CAN_sendMessage(CANA_BASE, 1, MSG_DATA_LENGTH, txMsgData);
-
- //
- // Delay before receiving the data
- //
- DEVICE_DELAY_US(500000);
-
- //
- // Read CAN message object 2 and check for new data
- //
- if (CAN_readMessage(CANA_BASE, 2, rxMsgData))
- {
- //
- // Check that received data matches sent data.
- // Device will halt here during debug if data doesn't match.
- //
- if((txMsgData[0] != rxMsgData[0]) ||
- (txMsgData[1] != rxMsgData[1]))
- {
- Example_Fail = 1;
- asm(" ESTOP0");
- }
- else
- {
- //
- // Increment message received counter
- //
- msgCount++;
- Example_PassCount++;
- }
- }
- else
- {
- //
- // Device will halt here during debug if no new data was received.
- //
- Example_Fail = 1;
- asm(" ESTOP0");
- }
- //
- // Increment the value in the transmitted message data.
- //
- txMsgData[0] += 0x01;
- txMsgData[1] += 0x01;
- //
- // Reset data if exceeds a byte
- //
- if(txMsgData[0] > 0xFF)
- {
- txMsgData[0] = 0;
- }
- if(txMsgData[1] > 0xFF)
- {
- txMsgData[1] = 0;
- }
- }
- }
1、 Device_init(); //看门狗时钟
2、Device_initGPIO(); //实际只是解除锁定,没有真正配置
2.1 设置引脚模式
3、外设初始化(可以包括引脚复用)
4、Interrupt_initModule();
5、Interrupt_initVectorTable();
6、// Enable Global Interrupt (INTM) and realtime interrupt (DBGM) //开全局中断
EINT;
ERTM;
7、使能外设
1、Device_init()函数的说明
// Function to initialize the device. Primarily initializes system control to a
// known state by disabling the watchdog, setting up the SYSCLKOUT frequency,
// and enabling the clocks to the peripherals.
// The function also configures the GPIO pins 22 and 23 in digital mode.
// To configure these pins as analog pins, use the function GPIO_setAnalogMode
2、GPIO引脚说明
在文件 FILE: pin_map.h 定义了每个引脚并用的模式
在device.h里面的引脚宏定义都是来自 pin_map.h,往下就是寄存器地址了,寄存器编程。
以CAN协议为例
- //from device.h
- // CAN External Loopback
- //
- #define DEVICE_GPIO_CFG_CANRXA GPIO_30_CANA_RX // "pinConfig" for CANA RX
- #define DEVICE_GPIO_CFG_CANTXA GPIO_31_CANA_TX // "pinConfig" for CANA TX
- #define DEVICE_GPIO_CFG_CANRXB GPIO_10_CANB_RX // "pinConfig" for CANB RX
- #define DEVICE_GPIO_CFG_CANTXB GPIO_8_CANB_TX // "pinConfig" for CANB TX
- // form pin_map.h
-
- #define GPIO_30_GPIO30 0x00081C00U
- #define GPIO_30_CANA_RX 0x00081C01U
- #define GPIO_30_SPIB_SIMO 0x00081C03U
- #define GPIO_30_OUTPUTXBAR7 0x00081C05U
- #define GPIO_30_EQEP1_STROBE 0x00081C06U
- #define GPIO_30_SD1_D4 0x00081C07U
-
- #define GPIO_31_GPIO31 0x00081E00U
- #define GPIO_31_CANA_TX 0x00081E01U
- #define GPIO_31_SPIB_SOMI 0x00081E03U
- #define GPIO_31_OUTPUTXBAR8 0x00081E05U
- #define GPIO_31_EQEP1_INDEX 0x00081E06U
- #define GPIO_31_SD1_C4 0x00081E07U
- #define GPIO_31_FSIRXA_D1 0x00081E09U
- from device.h
-
- #define DEVICE_GPIO_CFG_CANRXA GPIO_30_CANA_RX // "pinConfig" for CANA RX
- #define DEVICE_GPIO_CFG_CANTXA GPIO_31_CANA_TX // "pinConfig" for CANA TX
- #define DEVICE_GPIO_CFG_CANRXB GPIO_10_CANB_RX // "pinConfig" for CANB RX
- #define DEVICE_GPIO_CFG_CANTXB GPIO_8_CANB_TX // "pinConfig" for CANB TX
GPIO_setPinConfig(uint32_t pinConfig);
//! Configures the alternate function of a GPIO pin.
//!
//! \param pinConfig is the pin configuration value, specified as only one
//! of the \b GPIO_#_???? values.
//!
//! This function configures the pin mux that selects the peripheral function
//! associated with a particular GPIO pin. Only one peripheral function at a
//! time can be associated with a GPIO pin, and each peripheral function should
//! only be associated with a single GPIO pin at a time (despite the fact that
//! many of them can be associated with more than one GPIO pin).
GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
- from device.h
-
- #define DEVICE_GPIO_PIN_LED1 31U // GPIO number for LD2
- #define DEVICE_GPIO_PIN_LED2 34U // GPIO number for LD3
- #define DEVICE_GPIO_CFG_LED1 GPIO_31_GPIO31 // "pinConfig" for LD2
- #define DEVICE_GPIO_CFG_LED2 GPIO_34_GPIO34 // "pinConfig" for LD3
GPIO_setPadConfig(uint32_t pin, uint32_t pinType)
//! Sets the pad configuration for the specified pin.
//!
//! \param pin is the identifying GPIO number of the pin.
//! \param pinType specifies the pin type.
//!
//! This function sets the pin type for the specified pin. The parameter
//! \e pinType can be the following values:
//!
//! - \b GPIO_PIN_TYPE_STD specifies a push-pull output or a floating input
//! - \b GPIO_PIN_TYPE_PULLUP specifies the pull-up is enabled for an input
//! - \b GPIO_PIN_TYPE_OD specifies an open-drain output pin
//! - \b GPIO_PIN_TYPE_INVERT specifies inverted polarity on an input
GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode(uint32_t pin, GPIO_Direction pinIO);
//*****************************************************************************
//
//! Sets the direction and mode of the specified pin.
//!
//! \param pin is the identifying GPIO number of the pin.
//! \param pinIO is the pin direction mode.
//!
//! This function configures the specified pin on the selected GPIO port as
//! either input or output.
//!
//! The parameter \e pinIO is an enumerated data type that can be one of the
//! following values:
//!
//! - \b GPIO_DIR_MODE_IN
//! - \b GPIO_DIR_MODE_OUT
//!
//! where \b GPIO_DIR_MODE_IN specifies that the pin is programmed as an input
//! and \b GPIO_DIR_MODE_OUT specifies that the pin is programmed as an output.
//!
//! The pin is specified by its numerical value. For example, GPIO34 is
//! specified by passing 34 as \e pin.
- #define DEVICE_GPIO_PIN_CANTXA 31U // GPIO number for CANTXA(引脚号)
-
- #define DEVICE_GPIO_CFG_CANRXA GPIO_30_CANA_RX // "pinConfig" for CANA RX(引脚配置,pin_map.h文件中)
-
- //*****************************************************************************
- #define GPIO_PIN_TYPE_STD 0x0000U //!< Push-pull output or floating input
- #define GPIO_PIN_TYPE_PULLUP 0x0001U //!< Pull-up enable for input
- #define GPIO_PIN_TYPE_INVERT 0x0002U //!< Invert polarity on input
- #define GPIO_PIN_TYPE_OD 0x0004U //!< Open-drain on output
- #endif
-
- //*****************************************************************************
- //
- //! Values that can be passed to GPIO_setDirectionMode() as the \e pinIO
- //! parameter and returned from GPIO_getDirectionMode().
- //
- //*****************************************************************************
- typedef enum
- {
- GPIO_DIR_MODE_IN, //!< Pin is a GPIO input
- GPIO_DIR_MODE_OUT //!< Pin is a GPIO output
- } GPIO_Direction;
设置引脚GPIO和设置引脚复用,gpio.h
GPIO输入输出:
GPIO_setPadConfig(DEVICE_GPIO_PIN_LED1, GPIO_PIN_TYPE_STD);
GPIO_setDirectionMode(DEVICE_GPIO_PIN_LED1, GPIO_DIR_MODE_OUT);
GPIO_writePin(DEVICE_GPIO_PIN_LED1, 0);
GPIO_readPin(uint32_t pin)
GPIO复用:
GPIO_setPinConfig(DEVICE_GPIO_CFG_CANRXA);
GPIO_setPinConfig(DEVICE_GPIO_CFG_CANTXA);
(最好把文件打开对比着看,对文件结构里理解很到位,再配合上一篇建立工程,更好的理解了)
device.c,device.h ,driverlib.h 都是是TI做好的库函数
device.h 设备的引脚宏定义
driverlib.h 设备外设驱动的声明
- //from devicelib.h
-
- #include "inc/hw_memmap.h"
-
- #include "adc.h"
- #include "asysctl.h"
- #include "can.h"
- #include "cla.h"
- #include "clb.h"
- #include "clapromcrc.h"
- #include "cmpss.h"
- #include "cpu.h"
- #include "cputimer.h"
- #include "dac.h"
- #include "dcc.h"
- #include "dcsm.h"
- #include "debug.h"
- #include "dma.h"
- #include "ecap.h"
- #include "epwm.h"
- #include "eqep.h"
- #include "flash.h"
- #include "fsi.h"
- #include "gpio.h"
- #include "hrcap.h"
- #include "hrpwm.h"
- #include "i2c.h"
- #include "interrupt.h"
- #include "lin.h"
- #include "memcfg.h"
- #include "pga.h"
- #include "pin_map.h"
- #include "pin_map_legacy.h"
- #include "pmbus.h"
- #include "sci.h"
- #include "sdfm.h"
- #include "spi.h"
- #include "sysctl.h"
- #include "version.h"
- #include "xbar.h"
开头的 hw_memmap.h
// FILE: hw_memmap.h
//
// TITLE: Macros defining the memory map of the C28x.
最底层的寄存器宏定义,是E:\ti\c2000\C2000Ware_3_03_00_00\driverlib\f28004x\driverlib\inc,hw前缀的文件
// FILE: hw_adc.h
//
// TITLE: Definitions for the ADC registers.
再往上是 E:\ti\c2000\C2000Ware_3_03_00_00\driverlib\f28004x\driverlib 各种外设驱动文件
往上又是 E:\ti\c2000\C2000Ware_3_03_00_00\device_support\f28004x\common\include 的各种外设应用文件
编程时,写这两句,就把外设的驱动包括进来了
#include "driverlib.h"
#include "device.h"
再在工程中添加文件索引
E:\ti\c2000\C2000Ware_3_03_00_00\driverlib\f28004x\driverlib
在driverlib.h里面开头,#include "inc/hw_memmap.h",表示当前路径下inc文件夹里的hw_memmap.h,所以复制文件需要整个E:\ti\c2000\C2000Ware_3_03_00_00\driverlib\f28004x\driverlib下 的文件
再可以打开被#include "driverlib.h"引用的adc.h文件 ,开头就声明了,
- #include <stdbool.h>
- #include <stdint.h>
- #include "inc/hw_adc.h"
- #include "inc/hw_asysctl.h"
- #include "inc/hw_memmap.h"
- #include "inc/hw_types.h"
- #include "cpu.h"
- #include "debug.h"
发现 #include <stdbool.h> 这个文件就是编译器带的头文件了
所以需要在工程中添加文件索引
E:\ti\ccs1011\ccs\tools\compiler\ti-cgt-c2000_20.2.1.LTS\include
- //驱动里面没有这个函数,需要自己写
- // initADCs - Function to configure and power up ADCs A and B.
- //
- void initADCs(void)
- {
- //
- // Setup VREF as internal
- //
- ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
- ADC_setVREF(ADCB_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
-
- //
- // Set ADCCLK divider to /4
- //
- ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);
- ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_4_0);
-
- //
- // Set pulse positions to late
- //
- ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
- ADC_setInterruptPulseMode(ADCB_BASE, ADC_PULSE_END_OF_CONV);
-
- //
- // Power up the ADCs and then delay for 1 ms
- //
- ADC_enableConverter(ADCA_BASE);
- ADC_enableConverter(ADCB_BASE);
-
- DEVICE_DELAY_US(1000);
- }
- from can.h
- //
- // Initialize the CAN controller
- //
- CAN_initModule(CANA_BASE);
TI的外设初始化也是醉了,ADC初始化自己写个函数,SPI外设,建了个E:\CCS_workplace\spi_ex1_loopback\CPU1_RAM\syscfg board.c,board.h
使用外设之前可以先看看示例工程,这样还方便一下
中断触发方法的研究
中断优先级
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。