拆分CAN/DAC/DMA

This commit is contained in:
Stone 2016-06-14 08:41:19 +00:00
parent 3b14dd1104
commit 0885aa7e36
8 changed files with 351 additions and 302 deletions

View File

@ -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;
// 未完成
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

166
Platform/STM32F1/CAN.cpp Normal file
View File

@ -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;
// 未完成
}

61
Platform/STM32F1/DAC.cpp Normal file
View File

@ -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

92
Platform/STM32F1/DMA.cpp Normal file
View File

@ -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;
}