拆分CAN/DAC/DMA
This commit is contained in:
parent
3b14dd1104
commit
0885aa7e36
172
Device/CAN.cpp
172
Device/CAN.cpp
|
@ -1,15 +1,8 @@
|
||||||
#include "Sys.h"
|
#include "Type.h"
|
||||||
#include "Port.h"
|
#include "Platform\Pin.h"
|
||||||
|
|
||||||
#include "Can.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)
|
Can::Can(CAN index, Mode_TypeDef mode, int remap)
|
||||||
{
|
{
|
||||||
_index = index;
|
_index = index;
|
||||||
|
@ -18,165 +11,18 @@ Can::Can(CAN index, Mode_TypeDef mode, int remap)
|
||||||
|
|
||||||
_Tx = nullptr;
|
_Tx = nullptr;
|
||||||
_Rx = nullptr;
|
_Rx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/*外设时钟设置*/
|
void Can::Open()
|
||||||
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);
|
{
|
||||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
OnOpen();
|
||||||
/*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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Can::~Can()
|
Can::~Can()
|
||||||
{
|
{
|
||||||
auto tx = (CanTxMsg*)_Tx;
|
auto tx = (int*)_Tx;
|
||||||
delete tx;
|
delete tx;
|
||||||
|
|
||||||
auto rx = (CanRxMsg*)_Rx;
|
auto rx = (int*)_Rx;
|
||||||
delete 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;
|
|
||||||
// 未完成
|
|
||||||
}
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
Can(CAN index = Can1, Mode_TypeDef mode = Mode_Send, int remap = 1);
|
Can(CAN index = Can1, Mode_TypeDef mode = Mode_Send, int remap = 1);
|
||||||
~Can();
|
~Can();
|
||||||
|
|
||||||
|
void Open();
|
||||||
void Send(byte* buf, uint len);
|
void Send(byte* buf, uint len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -30,6 +31,8 @@ private:
|
||||||
|
|
||||||
void* _Tx;
|
void* _Tx;
|
||||||
void* _Rx;
|
void* _Rx;
|
||||||
|
|
||||||
|
void OnOpen();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "DAC.h"
|
#include "Port.h"
|
||||||
|
#include "DAC.h"
|
||||||
|
|
||||||
#include "Platform\stm32.h"
|
//#include "Platform\stm32.h"
|
||||||
|
|
||||||
#if defined(STM32F1)
|
#if defined(STM32F1)
|
||||||
DAConverter::DAConverter(Pin pin)
|
DAConverter::DAConverter(Pin pin)
|
||||||
|
@ -10,46 +11,25 @@ DAConverter::DAConverter(Pin pin)
|
||||||
debug_printf("Pin不能为空");
|
debug_printf("Pin不能为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pin == PA4)Channel = DAC_Channel_1;
|
|
||||||
else Channel = DAC_Channel_2;
|
|
||||||
|
|
||||||
Align = DAConverter::AlignR;
|
_Pin = pin;
|
||||||
|
|
||||||
|
OnInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DAConverter::Open()
|
bool DAConverter::Open()
|
||||||
{
|
{
|
||||||
// GPIO
|
return OnOpen();
|
||||||
// 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::Close()
|
bool DAConverter::Close()
|
||||||
{
|
{
|
||||||
DAC_Cmd(Channel, DISABLE);
|
return OnClose();
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB1Periph_DAC, DISABLE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DAConverter::Output(ushort dat) // 处理对齐问题
|
bool DAConverter::Write(ushort value) // 处理对齐问题
|
||||||
{
|
{
|
||||||
//if (Opened)return false;
|
return OnWrite(value);
|
||||||
if (Channel == DAC_Channel_1)
|
|
||||||
DAC_SetChannel1Data(Align, dat);
|
|
||||||
else
|
|
||||||
DAC_SetChannel2Data(Align, dat);
|
|
||||||
DAC_SoftwareTriggerCmd(Channel, ENABLE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
29
Device/DAC.h
29
Device/DAC.h
|
@ -1,12 +1,6 @@
|
||||||
#ifndef __DAC_H__
|
#ifndef __DAC_H__
|
||||||
#define __DAC_H__
|
#define __DAC_H__
|
||||||
|
|
||||||
#include "Port.h"
|
|
||||||
|
|
||||||
#if defined(STM32F1)
|
|
||||||
#include "stm32f10x_dac.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
STM32F1:
|
STM32F1:
|
||||||
两个DAC转换器:一个输出通道对应一个转换器
|
两个DAC转换器:一个输出通道对应一个转换器
|
||||||
|
@ -21,30 +15,27 @@ IO 设置为模拟输入(AIN)
|
||||||
PA4 PA5
|
PA4 PA5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DAConverter
|
class DAConverter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
byte Align;
|
||||||
|
|
||||||
#if defined(STM32F1)
|
AnalogInPort* Port = nullptr;
|
||||||
enum
|
|
||||||
{
|
|
||||||
AlignR = DAC_Align_12b_R,
|
|
||||||
AlignL = DAC_Align_12b_L,
|
|
||||||
Alignsht = DAC_Align_8b_R
|
|
||||||
}Align;
|
|
||||||
|
|
||||||
AnalogInPort * Port = nullptr;
|
|
||||||
|
|
||||||
byte Channel;
|
byte Channel;
|
||||||
DAConverter(Pin pin);
|
DAConverter(Pin pin);
|
||||||
|
|
||||||
bool Open();
|
bool Open();
|
||||||
bool Close();
|
bool Close();
|
||||||
bool Output(ushort dat);
|
bool Write(ushort value);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Pin _Pin;
|
||||||
|
|
||||||
|
void OnInit();
|
||||||
|
bool OnOpen();
|
||||||
|
bool OnClose();
|
||||||
|
bool OnWrite(ushort value);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,92 +1,2 @@
|
||||||
#include "Sys.h"
|
#include "Sys.h"
|
||||||
#include "DMA.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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
// 未完成
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue