From 0885aa7e3638b73a34f622dde94e037074b40931 Mon Sep 17 00:00:00 2001 From: Stone Date: Tue, 14 Jun 2016 08:41:19 +0000 Subject: [PATCH] =?UTF-8?q?=E6=8B=86=E5=88=86CAN/DAC/DMA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Device/CAN.cpp | 172 ++------------------------------------- Device/CAN.h | 3 + Device/DAC.cpp | 38 ++------- Device/DAC.h | 31 +++---- Device/DMA.cpp | 90 -------------------- Platform/STM32F1/CAN.cpp | 166 +++++++++++++++++++++++++++++++++++++ Platform/STM32F1/DAC.cpp | 61 ++++++++++++++ Platform/STM32F1/DMA.cpp | 92 +++++++++++++++++++++ 8 files changed, 351 insertions(+), 302 deletions(-) create mode 100644 Platform/STM32F1/CAN.cpp create mode 100644 Platform/STM32F1/DAC.cpp create mode 100644 Platform/STM32F1/DMA.cpp diff --git a/Device/CAN.cpp b/Device/CAN.cpp index fc345f9b..da93293c 100644 --- a/Device/CAN.cpp +++ b/Device/CAN.cpp @@ -1,15 +1,8 @@ -#include "Sys.h" -#include "Port.h" +#include "Type.h" +#include "Platform\Pin.h" + #include "Can.h" -#include "Platform\stm32.h" - -#ifdef STM32F1 -static const Pin g_CAN_Pins_Map[] = CAN_PINS; -static const Pin g_CAN_Pins_Map2[] = CAN_PINS_REMAP2; -static const Pin g_CAN_Pins_Map3[] = CAN_PINS_REMAP3; -#endif - Can::Can(CAN index, Mode_TypeDef mode, int remap) { _index = index; @@ -18,165 +11,18 @@ Can::Can(CAN index, Mode_TypeDef mode, int remap) _Tx = nullptr; _Rx = nullptr; +} - /*外设时钟设置*/ - //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); - /*IO设置*/ -#ifdef STM32F1 - if(index == Can1) - { - if(remap == 1) - GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); - else if(remap == 2) - GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE); - } - else if(index == Can2) - GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE); - - const Pin* p = g_CAN_Pins_Map; - if(remap == 2) - p = g_CAN_Pins_Map2; - else if(remap == 3) - p = g_CAN_Pins_Map3; - - AlternatePort tx(p[0]); - InputPort rx(p[1], false, InputPort::UP); -#endif - -#ifdef STM32F1 - Interrupt.SetPriority(USB_LP_CAN1_RX0_IRQn, 1); -#elif defined(STM32F4) - Interrupt.SetPriority(CAN1_RX0_IRQn, 1); -#endif - - /************************CAN通信参数设置**********************************/ - CAN_TypeDef* const g_CANs[] = CANS; - /*CAN寄存器初始化*/ - CAN_DeInit(g_CANs[_index]); - - CAN_InitTypeDef _can; - CAN_StructInit(&_can); - /*CAN单元初始化*/ - _can.CAN_TTCM = DISABLE; //MCR-TTCM 时间触发通信模式使能 - _can.CAN_ABOM = Mode == Mode_Send ? ENABLE : DISABLE; //MCR-ABOM 自动离线管理 - _can.CAN_AWUM = Mode == Mode_Send ? ENABLE : DISABLE; //MCR-AWUM 自动唤醒模式 - _can.CAN_NART = DISABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传 - _can.CAN_RFLM = DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文 - _can.CAN_TXFP = DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符 - _can.CAN_Mode = CAN_Mode_Normal; //正常发送模式 - _can.CAN_SJW = CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元 - _can.CAN_BS1 = CAN_BS1_3tq; //BTR-TS1 时间段1 占用了6个时间单元 - _can.CAN_BS2 = CAN_BS2_2tq; //BTR-TS1 时间段2 占用了3个时间单元 - _can.CAN_Prescaler = 6; ////BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+6+3)/4 = 0.8Mbps - CAN_Init(g_CANs[_index], &_can); - - if(Mode == Mode_Send) - _Tx = new CanTxMsg(); - else - { - _Rx = new CanRxMsg(); - - CAN_FilterInitTypeDef filter; - - /*CAN过滤器初始化*/ - filter.CAN_FilterNumber=0; //过滤器组0 - filter.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式 - filter.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。 - /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */ - - int slave_id = 1; - switch(Mode) - { - case EXT_Data: - //只接受扩展数据帧 - filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFF; - break; - case EXT_Remote: - //只接受扩展远程帧 - filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFF; - break; - case STD_Remote: - //只接受标准远程帧 - filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFF; - break; - case STD_Data: - //只接受标准数据帧 - filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFF; - break; - case EXT: - //扩展帧不会被过滤掉 - filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT)&0xFFFF; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFC; - break; - case STD: - //标准帧不会被过滤掉 - filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; - filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD)&0xffff; - filter.CAN_FilterMaskIdHigh = 0xFFFF; - filter.CAN_FilterMaskIdLow = 0xFFFC; - break; - case Mode_ALL: - //接收所有类型 - filter.CAN_FilterIdHigh = 0x0000; - filter.CAN_FilterIdLow = 0x0000; - filter.CAN_FilterMaskIdHigh = 0x0000; - filter.CAN_FilterMaskIdLow = 0x0000; - } - - filter.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ; //过滤器被关联到FIFO0 - filter.CAN_FilterActivation=ENABLE; //使能过滤器 - CAN_FilterInit(&filter); - /*CAN通信中断使能*/ - CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); - } +void Can::Open() +{ + OnOpen(); } Can::~Can() { - auto tx = (CanTxMsg*)_Tx; + auto tx = (int*)_Tx; delete tx; - auto rx = (CanRxMsg*)_Rx; + auto rx = (int*)_Rx; delete rx; } - -void Can::Send(byte* buf, uint len) -{ - auto tx = (CanTxMsg*)_Tx; - switch(Mode) - { - case STD_Data: - case STD_Remote: - case STD: - tx->StdId = 0; - tx->IDE = CAN_ID_STD; - break; - case EXT_Data: - case EXT_Remote: - case EXT: - tx->StdId = 0; - tx->IDE = CAN_ID_EXT; - break; - } - - tx->RTR =CAN_RTR_DATA; //发送的是数据 - tx->DLC =2; //数据长度为2字节 - tx->Data[0] = 0x12; - tx->Data[1] = 0x34; - // 未完成 -} diff --git a/Device/CAN.h b/Device/CAN.h index c07d2adb..68476629 100644 --- a/Device/CAN.h +++ b/Device/CAN.h @@ -22,6 +22,7 @@ public: Can(CAN index = Can1, Mode_TypeDef mode = Mode_Send, int remap = 1); ~Can(); + void Open(); void Send(byte* buf, uint len); private: @@ -30,6 +31,8 @@ private: void* _Tx; void* _Rx; + + void OnOpen(); }; #endif diff --git a/Device/DAC.cpp b/Device/DAC.cpp index ac8ca509..5ab9a444 100644 --- a/Device/DAC.cpp +++ b/Device/DAC.cpp @@ -1,6 +1,7 @@ -#include "DAC.h" +#include "Port.h" +#include "DAC.h" -#include "Platform\stm32.h" +//#include "Platform\stm32.h" #if defined(STM32F1) DAConverter::DAConverter(Pin pin) @@ -10,46 +11,25 @@ DAConverter::DAConverter(Pin pin) debug_printf("Pin不能为空"); return; } - if (pin == PA4)Channel = DAC_Channel_1; - else Channel = DAC_Channel_2; - Align = DAConverter::AlignR; + _Pin = pin; + OnInit(); } bool DAConverter::Open() { - // GPIO - // DAC 变换器 - RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - DAC_InitTypeDef adccfg; - DAC_StructInit(&adccfg); - //adccfg.DAC_Trigger = DAC_Trigger_None; // 不使用外部触发 - adccfg.DAC_Trigger = DAC_Trigger_Software; // 使用软件触发 - adccfg.DAC_WaveGeneration = DAC_WaveGeneration_None; // 不使用波形发生器 - adccfg.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; // 屏蔽幅值设置 - adccfg.DAC_OutputBuffer = DISABLE; // 不使用缓冲器 - DAC_Init(Channel, &adccfg); - DAC_Cmd(Channel, ENABLE); - return true; + return OnOpen(); } bool DAConverter::Close() { - DAC_Cmd(Channel, DISABLE); - RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, DISABLE); - return true; + return OnClose(); } -bool DAConverter::Output(ushort dat) // 处理对齐问题 +bool DAConverter::Write(ushort value) // 处理对齐问题 { - //if (Opened)return false; - if (Channel == DAC_Channel_1) - DAC_SetChannel1Data(Align, dat); - else - DAC_SetChannel2Data(Align, dat); - DAC_SoftwareTriggerCmd(Channel, ENABLE); - return true; + return OnWrite(value); } #endif diff --git a/Device/DAC.h b/Device/DAC.h index e069f720..5a3733cf 100644 --- a/Device/DAC.h +++ b/Device/DAC.h @@ -1,12 +1,6 @@ #ifndef __DAC_H__ #define __DAC_H__ -#include "Port.h" - -#if defined(STM32F1) -#include "stm32f10x_dac.h" -#endif - /* STM32F1: 两个DAC转换器:一个输出通道对应一个转换器 @@ -18,33 +12,30 @@ DAC同步更新 分别更新 外部触发参考 以 Vref+ 为参考 IO 设置为模拟输入(AIN) -PA4 PA5 +PA4 PA5 */ - - class DAConverter { public: + byte Align; -#if defined(STM32F1) - enum - { - AlignR = DAC_Align_12b_R, - AlignL = DAC_Align_12b_L, - Alignsht = DAC_Align_8b_R - }Align; - - AnalogInPort * Port = nullptr; + AnalogInPort* Port = nullptr; byte Channel; DAConverter(Pin pin); bool Open(); bool Close(); - bool Output(ushort dat); -#endif + bool Write(ushort value); +private: + Pin _Pin; + + void OnInit(); + bool OnOpen(); + bool OnClose(); + bool OnWrite(ushort value); }; #endif diff --git a/Device/DMA.cpp b/Device/DMA.cpp index d107b202..b45c1409 100644 --- a/Device/DMA.cpp +++ b/Device/DMA.cpp @@ -1,92 +1,2 @@ #include "Sys.h" #include "DMA.h" - -#include "Platform\stm32.h" - -bool DMA::Start() -{ -#ifdef STM32F4 - DMA_InitTypeDef DMA_InitStructure; - __IO uint32_t Timeout = TIMEOUT_MAX; - - /* Enable DMA clock */ - RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE); - - /* Reset DMA Stream registers (for debug purpose) */ - DMA_DeInit(DMA_STREAM); - - /* Check if the DMA Stream is disabled before enabling it. - Note that this step is useful when the same Stream is used multiple times: - enabled, then disabled then re-enabled... In this case, the DMA Stream disable - will be effective only at the end of the ongoing data transfer and it will - not be possible to re-configure it before making sure that the Enable bit - has been cleared by hardware. If the Stream is used only once, this step might - be bypassed. */ - while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE) - { - } - - /* Configure DMA Stream */ - DMA_InitStructure.DMA_Channel = DMA_CHANNEL; - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer; - DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)DST_Buffer; - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; - DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_High; - DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; - DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; - DMA_Init(DMA_STREAM, &DMA_InitStructure); - - /* Enable DMA Stream Transfer Complete interrupt */ - DMA_ITConfig(DMA_STREAM, DMA_IT_TC, ENABLE); - - /* DMA Stream enable */ - DMA_Cmd(DMA_STREAM, ENABLE); - - /* Check if the DMA Stream has been effectively enabled. - The DMA Stream Enable bit is cleared immediately by hardware if there is an - error in the configuration parameters and the transfer is no started (ie. when - wrong FIFO threshold is configured ...) */ - Timeout = TIMEOUT_MAX; - while ((DMA_GetCmdStatus(DMA_STREAM) != ENABLE) && (Timeout-- > 0)) - { - } - - /* Check if a timeout condition occurred */ - if (Timeout == 0) - { - /* Manage the error: to simplify the code enter an infinite loop */ - while (1) - { - } - } - - Interrupt.Enable(DMA_STREAM_IRQ); -#endif - - return true; -} - -bool DMA::WaitForStop() -{ -#ifdef STM32F4 - uint retry = Retry; - //while (DMA_GetCurrentMemoryTarget(DMA_STREAM) != 0) - while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE) - { - if(--retry <= 0) - { - Error++; - return false; - } - } -#endif - return true; -} diff --git a/Platform/STM32F1/CAN.cpp b/Platform/STM32F1/CAN.cpp new file mode 100644 index 00000000..6372b1c7 --- /dev/null +++ b/Platform/STM32F1/CAN.cpp @@ -0,0 +1,166 @@ +#include "Sys.h" +#include "Port.h" +#include "Can.h" + +#include "Platform\stm32.h" + +#ifdef STM32F1 +static const Pin g_CAN_Pins_Map[] = CAN_PINS; +static const Pin g_CAN_Pins_Map2[] = CAN_PINS_REMAP2; +static const Pin g_CAN_Pins_Map3[] = CAN_PINS_REMAP3; +#endif + +void Can::OnOpen() +{ + /*外设时钟设置*/ + //RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); + /*IO设置*/ +#ifdef STM32F1 + if(index == Can1) + { + if(remap == 1) + GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); + else if(remap == 2) + GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE); + } + else if(index == Can2) + GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE); + + const Pin* p = g_CAN_Pins_Map; + if(remap == 2) + p = g_CAN_Pins_Map2; + else if(remap == 3) + p = g_CAN_Pins_Map3; + + AlternatePort tx(p[0]); + InputPort rx(p[1], false, InputPort::UP); +#endif + +#ifdef STM32F1 + Interrupt.SetPriority(USB_LP_CAN1_RX0_IRQn, 1); +#elif defined(STM32F4) + Interrupt.SetPriority(CAN1_RX0_IRQn, 1); +#endif + + /************************CAN通信参数设置**********************************/ + CAN_TypeDef* const g_CANs[] = CANS; + /*CAN寄存器初始化*/ + CAN_DeInit(g_CANs[_index]); + + CAN_InitTypeDef _can; + CAN_StructInit(&_can); + /*CAN单元初始化*/ + _can.CAN_TTCM = DISABLE; //MCR-TTCM 时间触发通信模式使能 + _can.CAN_ABOM = Mode == Mode_Send ? ENABLE : DISABLE; //MCR-ABOM 自动离线管理 + _can.CAN_AWUM = Mode == Mode_Send ? ENABLE : DISABLE; //MCR-AWUM 自动唤醒模式 + _can.CAN_NART = DISABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传 + _can.CAN_RFLM = DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文 + _can.CAN_TXFP = DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符 + _can.CAN_Mode = CAN_Mode_Normal; //正常发送模式 + _can.CAN_SJW = CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 2个时间单元 + _can.CAN_BS1 = CAN_BS1_3tq; //BTR-TS1 时间段1 占用了6个时间单元 + _can.CAN_BS2 = CAN_BS2_2tq; //BTR-TS1 时间段2 占用了3个时间单元 + _can.CAN_Prescaler = 6; ////BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+6+3)/4 = 0.8Mbps + CAN_Init(g_CANs[_index], &_can); + + if(Mode == Mode_Send) + _Tx = new CanTxMsg(); + else + { + _Rx = new CanRxMsg(); + + CAN_FilterInitTypeDef filter; + + /*CAN过滤器初始化*/ + filter.CAN_FilterNumber=0; //过滤器组0 + filter.CAN_FilterMode=CAN_FilterMode_IdMask; //工作在标识符屏蔽位模式 + filter.CAN_FilterScale=CAN_FilterScale_32bit; //过滤器位宽为单个32位。 + /* 使能报文标示符过滤器按照标示符的内容进行比对过滤,扩展ID不是如下的就抛弃掉,是的话,会存入FIFO0。 */ + + int slave_id = 1; + switch(Mode) + { + case EXT_Data: + //只接受扩展数据帧 + filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFF; + break; + case EXT_Remote: + //只接受扩展远程帧 + filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT|CAN_RTR_REMOTE)&0xFFFF; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFF; + break; + case STD_Remote: + //只接受标准远程帧 + filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD|CAN_RTR_REMOTE)&0xffff; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFF; + break; + case STD_Data: + //只接受标准数据帧 + filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD|CAN_RTR_DATA)&0xffff; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFF; + break; + case EXT: + //扩展帧不会被过滤掉 + filter.CAN_FilterIdHigh = ((slave_id<<3)&0xFFFF0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<3)|CAN_ID_EXT)&0xFFFF; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFC; + break; + case STD: + //标准帧不会被过滤掉 + filter.CAN_FilterIdHigh = ((slave_id<<21)&0xffff0000)>>16; + filter.CAN_FilterIdLow = ((slave_id<<21)|CAN_ID_STD)&0xffff; + filter.CAN_FilterMaskIdHigh = 0xFFFF; + filter.CAN_FilterMaskIdLow = 0xFFFC; + break; + case Mode_ALL: + //接收所有类型 + filter.CAN_FilterIdHigh = 0x0000; + filter.CAN_FilterIdLow = 0x0000; + filter.CAN_FilterMaskIdHigh = 0x0000; + filter.CAN_FilterMaskIdLow = 0x0000; + } + + filter.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ; //过滤器被关联到FIFO0 + filter.CAN_FilterActivation=ENABLE; //使能过滤器 + CAN_FilterInit(&filter); + /*CAN通信中断使能*/ + CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); + } +} + +void Can::Send(byte* buf, uint len) +{ + auto tx = (CanTxMsg*)_Tx; + switch(Mode) + { + case STD_Data: + case STD_Remote: + case STD: + tx->StdId = 0; + tx->IDE = CAN_ID_STD; + break; + case EXT_Data: + case EXT_Remote: + case EXT: + tx->StdId = 0; + tx->IDE = CAN_ID_EXT; + break; + } + + tx->RTR =CAN_RTR_DATA; //发送的是数据 + tx->DLC =2; //数据长度为2字节 + tx->Data[0] = 0x12; + tx->Data[1] = 0x34; + // 未完成 +} diff --git a/Platform/STM32F1/DAC.cpp b/Platform/STM32F1/DAC.cpp new file mode 100644 index 00000000..465155e7 --- /dev/null +++ b/Platform/STM32F1/DAC.cpp @@ -0,0 +1,61 @@ +#include "DAC.h" + +#include "Platform\stm32.h" + +/*enum +{ + AlignR = DAC_Align_12b_R, + AlignL = DAC_Align_12b_L, + Alignsht = DAC_Align_8b_R +}Align;*/ + +#if defined(STM32F1) +void DAConverter::OnInit() +{ + if (_Pin == PA4) + Channel = DAC_Channel_1; + else + Channel = DAC_Channel_2; + + Align = DAC_Align_12b_R; +} + +bool DAConverter::OnOpen() +{ + // GPIO + // DAC 变换器 + RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); + DAC_InitTypeDef adccfg; + DAC_StructInit(&adccfg); + //adccfg.DAC_Trigger = DAC_Trigger_None; // 不使用外部触发 + adccfg.DAC_Trigger = DAC_Trigger_Software; // 使用软件触发 + adccfg.DAC_WaveGeneration = DAC_WaveGeneration_None; // 不使用波形发生器 + adccfg.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0; // 屏蔽幅值设置 + adccfg.DAC_OutputBuffer = DISABLE; // 不使用缓冲器 + DAC_Init(Channel, &adccfg); + DAC_Cmd(Channel, ENABLE); + + return true; +} + +bool DAConverter::OnClose() +{ + DAC_Cmd(Channel, DISABLE); + RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, DISABLE); + + return true; +} + +bool DAConverter::OnWrite(ushort value) // 处理对齐问题 +{ + //if (Opened)return false; + if (Channel == DAC_Channel_1) + DAC_SetChannel1Data(Align, dat); + else + DAC_SetChannel2Data(Align, dat); + DAC_SoftwareTriggerCmd(Channel, ENABLE); + + return true; +} + +#endif diff --git a/Platform/STM32F1/DMA.cpp b/Platform/STM32F1/DMA.cpp new file mode 100644 index 00000000..d107b202 --- /dev/null +++ b/Platform/STM32F1/DMA.cpp @@ -0,0 +1,92 @@ +#include "Sys.h" +#include "DMA.h" + +#include "Platform\stm32.h" + +bool DMA::Start() +{ +#ifdef STM32F4 + DMA_InitTypeDef DMA_InitStructure; + __IO uint32_t Timeout = TIMEOUT_MAX; + + /* Enable DMA clock */ + RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE); + + /* Reset DMA Stream registers (for debug purpose) */ + DMA_DeInit(DMA_STREAM); + + /* Check if the DMA Stream is disabled before enabling it. + Note that this step is useful when the same Stream is used multiple times: + enabled, then disabled then re-enabled... In this case, the DMA Stream disable + will be effective only at the end of the ongoing data transfer and it will + not be possible to re-configure it before making sure that the Enable bit + has been cleared by hardware. If the Stream is used only once, this step might + be bypassed. */ + while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE) + { + } + + /* Configure DMA Stream */ + DMA_InitStructure.DMA_Channel = DMA_CHANNEL; + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer; + DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)DST_Buffer; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; + DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(DMA_STREAM, &DMA_InitStructure); + + /* Enable DMA Stream Transfer Complete interrupt */ + DMA_ITConfig(DMA_STREAM, DMA_IT_TC, ENABLE); + + /* DMA Stream enable */ + DMA_Cmd(DMA_STREAM, ENABLE); + + /* Check if the DMA Stream has been effectively enabled. + The DMA Stream Enable bit is cleared immediately by hardware if there is an + error in the configuration parameters and the transfer is no started (ie. when + wrong FIFO threshold is configured ...) */ + Timeout = TIMEOUT_MAX; + while ((DMA_GetCmdStatus(DMA_STREAM) != ENABLE) && (Timeout-- > 0)) + { + } + + /* Check if a timeout condition occurred */ + if (Timeout == 0) + { + /* Manage the error: to simplify the code enter an infinite loop */ + while (1) + { + } + } + + Interrupt.Enable(DMA_STREAM_IRQ); +#endif + + return true; +} + +bool DMA::WaitForStop() +{ +#ifdef STM32F4 + uint retry = Retry; + //while (DMA_GetCurrentMemoryTarget(DMA_STREAM) != 0) + while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE) + { + if(--retry <= 0) + { + Error++; + return false; + } + } +#endif + return true; +}