.ioc




malloc.c

#include "malloc.h"       //内存池(32字节对齐)
__align(32) u8 membase[MEM_MAX_SIZE] __attribute__((at(0XC0000000)));                   //外部SDRAM内存池,前面2M给LTDC用了(1280*800*2)
//内存管理表                                             //内部SRAM内存池MAP
u32 memmapbase[MEM_ALLOC_TABLE_SIZE] __attribute__((at(0XC0000000+MEM_MAX_SIZE))); //外部SRAM内存池MAP
//内存管理参数
const u32 memtblsize=MEM_ALLOC_TABLE_SIZE; //内存表大小
const u32 memblksize=MEM_BLOCK_SIZE;                   //内存分块大小
const u32 memsize=MEM_MAX_SIZE;                            //内存总大小//内存管理控制器
struct _m_mallco_dev mallco_dev=
{my_mem_init,                       //内存初始化my_mem_perused,                      //内存使用率membase,                             //内存池memmapbase,                        //内存管理状态表0                              //内存管理未就绪
};
//复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n)
{  u8 *xdes=des;u8 *xsrc=src; while(n--)*xdes++=*xsrc++;
}
//设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void *s,u8 c,u32 count)
{  u8 *xs = s;  while(count--)*xs++=c;
}
//内存管理初始化
//memx:所属内存块
void my_mem_init(void)
{  mymemset(mallco_dev.memmap,0,memtblsize*4);  //内存状态表数据清零  mallco_dev.memrdy=1;                              //内存管理初始化OK
}
//获取内存使用率
//memx:所属内存块
//返回值:使用率(扩大了10倍,0~1000,代表0.0%~100.0%)
u16 my_mem_perused(void)
{  u32 used=0;  u32 i;  for(i=0;i<memtblsize;i++)  {  if(mallco_dev.memmap[i])used++; } return (used*1000)/(memtblsize);
}
//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 my_mem_malloc(u32 size)
{  signed long offset=0;  u32 nmemb;   //需要的内存块数  u32 cmemb=0;//连续空内存块数u32 i;  if(!mallco_dev.memrdy)my_mem_init();//未初始化,先执行初始化 if(size==0)return 0XFFFFFFFF;//不需要分配nmemb=size/memblksize;    //获取需要分配的连续内存块数if(size%memblksize)nmemb++;  for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区  {     if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加else cmemb=0;                              //连续内存块清零if(cmemb==nmemb)                         //找到了连续nmemb个空内存块{for(i=0;i<nmemb;i++)                    //标注内存块非空 {  mallco_dev.memmap[offset+i]=nmemb;  }  return (offset*memblksize);//返回偏移地址  }}  return 0XFFFFFFFF;//未找到符合分配条件的内存块
}
//释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 my_mem_free(u32 offset)
{  int i;  if(!mallco_dev.memrdy)//未初始化,先执行初始化{my_mem_init();    return 1;//未初始化  }  if(offset<memsize)//偏移在内存池内. {  int index=offset/memblksize;           //偏移所在内存块号码  int nmemb=mallco_dev.memmap[index];   //内存块数量for(i=0;i<nmemb;i++)                       //内存块清零{  mallco_dev.memmap[index+i]=0;  }  return 0;  }else return 2;//偏移超区了.
}
//释放内存(外部调用)
//memx:所属内存块
//ptr:内存首地址
void myfree(void *ptr)
{  u32 offset;   if(ptr==NULL)return;//地址为0.  offset=(u32)ptr-(u32)mallco_dev.membase;     my_mem_free(offset);  //释放内存
}
//分配内存(外部调用)
//memx:所属内存块
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u32 size)
{  u32 offset;   offset=my_mem_malloc(size);              if(offset==0XFFFFFFFF)return NULL;  else return (void*)((u32)mallco_dev.membase+offset);
}
//重新分配内存(外部调用)
//memx:所属内存块
//*ptr:旧内存首地址
//size:要分配的内存大小(字节)
//返回值:新分配到的内存首地址.
void *myrealloc(void *ptr,u32 size)
{  u32 offset;    offset=my_mem_malloc(size);      if(offset==0XFFFFFFFF)return NULL;     else  {                                       mymemcpy((void*)((u32)mallco_dev.membase+offset),ptr,size); //拷贝旧内存内容到新内存   myfree(ptr);                                                    //释放旧内存return (void*)((u32)mallco_dev.membase+offset);                 //返回新内存首地址}
}

malloc.h

#ifndef __MALLOC_H
#define __MALLOC_H
#include "sys.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32开发板
//内存管理 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/13
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//   #ifndef NULL
#define NULL 0
#endif//mem2内存参数设定.mem2的内存池处于外部SDRAM里面
#define MEM_BLOCK_SIZE          64                              //内存块大小为64字节
#define MEM_MAX_SIZE             (30840 *1024)              //最大管理内存32263K
#define MEM_ALLOC_TABLE_SIZE    MEM_MAX_SIZE/MEM_BLOCK_SIZE     //内存表大小//内存管理控制器
struct _m_mallco_dev
{void (*init)(void);                    //初始化u16 (*perused)(void);                  //内存使用率u8   *membase;               //内存池 管理SRAMBANK个区域的内存u32 *memmap;              //内存管理状态表u8  memrdy;                //内存管理是否就绪
};
extern struct _m_mallco_dev mallco_dev;  //在mallco.c里面定义void mymemset(void *s,u8 c,u32 count);  //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存
void my_mem_init(void);             //内存管理初始化函数(外/内部调用)
u32 my_mem_malloc(u32 size);    //内存分配(内部调用)
u8 my_mem_free(u32 offset);     //内存释放(内部调用)
u16 my_mem_perused(void) ;          //获得内存使用率(外/内部调用) 

//用户调用函数
void myfree(void *ptr);             //内存释放(外部调用)
void *mymalloc(u32 size);           //内存分配(外部调用)
void *myrealloc(void *ptr,u32 size);//重新分配内存(外部调用)
#endif

bsp.c

#include "bsp.h"
/*
*********************************************************************************************************
*   函 数 名: bsp_Init
*   功能说明: 初始化硬件设备。只需要调用一次。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。
*            全局变量。
*   形    参: 无
*   返 回 值: 无
*********************************************************************************************************
*/
void bsp_Init(void)
{SDRAM_Initialization_Sequence(&hsdram1);/*SDRAM初始化*/my_mem_init();         //初始化外部内存池
//  bsp_InitUart();     /* 初始化串口 */
//  bsp_CAN_Init();
//  bsp_flashInit();    /*flash 读取存储的温度*///bsp_InitSram();   /* 初始sram  测试 */
//bsp_Initcan();        /* 初始can1  */HAL_TIM_Base_Start_IT(&htim4);        //启动定时器TIM3
}

bsp.h

/*
*********************************************************************************************************
*
*   模块名称 : 驱动模块
*   文件名称 : bsp.h
*   版    本 : V1.0
*   说    明 : 头文件
*
*
*********************************************************************************************************
*/
#ifndef __BSP_H__
#define __BSP_H__#include <string.h>
#include <stdio.h>
#include "stm32f4xx_hal.h"
#include "main.h"
#include "looplist.h"
#include "sys.h"
#include "app_main.h"
//#include "epos_thread.h"
//#include "motor_thread.h"
//#include "smc_thread.h"
//#include "bsp_modbushost.h"
//#include "bsp_modbusslave.h"
#include "main_thread.h"
#include "led_thread.h"
//#include "bsp_epos2.h"
//#include "sys_stru.h"//#include "bsp_DWT.h"
//#include "pub_delay.h"//#include "bsp_spi.h"
//#include "bsp_w25qxx.h"
#include "bsp_led.h"
//#include "bsp_usart.h"
//#include "bsp_can.h"
//#include "bsp_interflash.h"
#include "bsp_sdram.h"
#include "malloc.h"
#include "tim.h"
#include "canopen_drv.h"
/* 供外部调用的函数声明 */
void bsp_Init(void);#endif

app_main.c

#include "bsp.h"
#include "cmsis_os2.h"
#include "app_main.h"/* 任务句柄 */
osThreadId_t    main_ids  = NULL;
osThreadId_t    led_ids = NULL;
osThreadId_t    cantx_ids = NULL;
osThreadId_t    canrx_ids = NULL;
/*timer*/
osTimerId_t  timer0_id;
osTimerId_t  timer1_id;
osTimerId_t  timer2_id;/*semaphore*/
osSemaphoreId_t     sid_Semaphore_softtimer0;
osSemaphoreId_t     sid_Semaphore_softtimer1;
osSemaphoreId_t     sid_Semaphore_softtimer2;/*event*/
osEventFlagsId_t    mid_event_Inited;/*queue*/
osMessageQueueId_t  mid_MsgQueue_usart1_rx;
osMessageQueueId_t  mid_MsgQueue_Set_temperature;
osMessageQueueId_t  mid_MsgQueue_feedbak_temperature;
osMessageQueueId_t  mid_MsgQueue_usart1_rx_falshupdata;
osMessageQueueId_t  osMQId_Can1Tx;
osMessageQueueId_t  osMQId_Can1Rx;unsigned short TimeOut=0;/*----------------------------------------------------------------------------
Initilise main thread*---------------------------------------------------------------------------*/static  osThreadAttr_t ThreadAttr_MAIN = {.name = "Main_Thread",             ///< name of the thread                              .attr_bits =NULL,                          ///< attribute bits.cb_mem=NULL,                                    ///< memory for control block.cb_size=NULL,                             ///< size of provided memory for control block
//.stack_mem=NULL,                         ///< memory for stack.stack_size =THREAD_MAIN_SIZE,///< size of stack.priority=osPriorityNormal,        ///< initial thread priority (default: osPriorityNormal).tz_module=NULL,                            ///< TrustZone module identifier.reserved=NULL,                             ///< reserved (must be 0)
};/*----------------------------------------------------------------------------
Initilise led thread*---------------------------------------------------------------------------*/static  osThreadAttr_t ThreadAttr_LED = {.name = "LED_Thread",                ///< name of the thread                              .attr_bits =NULL,                          ///< attribute bits.cb_mem=NULL,                                    ///< memory for control block.cb_size=NULL,                             ///< size of provided memory for control block
//.stack_mem=NULL,                         ///< memory for stack.stack_size =THREAD_LED_SIZE,///< size of stack.priority=osPriorityNormal,     ///< initial thread priority (default: osPriorityNormal).tz_module=NULL,                            ///< TrustZone module identifier.reserved=NULL,                             ///< reserved (must be 0)
};/*----------------------------------------------------------------------------
Initilise cansend thread*---------------------------------------------------------------------------*/static  osThreadAttr_t ThreadAttr_CanTx = {.name = "CanSend_Thread",              ///< name of the thread                              .attr_bits =NULL,                          ///< attribute bits.cb_mem=NULL,                                    ///< memory for control block.cb_size=NULL,                             ///< size of provided memory for control block
//.stack_mem=NULL,                         ///< memory for stack.stack_size =THREAD_CANTX_SIZE,///< size of stack.priority=osPriorityNormal,       ///< initial thread priority (default: osPriorityNormal).tz_module=NULL,                            ///< TrustZone module identifier.reserved=NULL,                             ///< reserved (must be 0)
};/*----------------------------------------------------------------------------
Initilise canrecive thread*---------------------------------------------------------------------------*/static  osThreadAttr_t ThreadAttr_CanRx = {.name = "CanRecive_Thread",              ///< name of the thread                              .attr_bits =NULL,                          ///< attribute bits.cb_mem=NULL,                                    ///< memory for control block.cb_size=NULL,                             ///< size of provided memory for control block
//.stack_mem=NULL,                         ///< memory for stack.stack_size =THREAD_CANRX_SIZE,///< size of stack.priority=osPriorityNormal,       ///< initial thread priority (default: osPriorityNormal).tz_module=NULL,                            ///< TrustZone module identifier.reserved=NULL,                             ///< reserved (must be 0)
};/*
*********************************************************************************************************
*   函 数 名: AppTaskCreate
*   功能说明: 创建应用任务
*   形    参: 无
*   返 回 值: 无
*********************************************************************************************************
*/static void AppTaskCreate (void)
{//main_taskThreadAttr_MAIN.stack_mem = mymalloc(THREAD_MAIN_SIZE);main_ids=osThreadNew(main_task, NULL, &ThreadAttr_MAIN);//led_taskThreadAttr_LED.stack_mem = mymalloc(THREAD_LED_SIZE);led_ids=osThreadNew(led_task, NULL, &ThreadAttr_LED);//canrx_taskThreadAttr_CanTx.stack_mem = mymalloc(THREAD_CANTX_SIZE);canrx_ids=osThreadNew(thread_canopen_rx, NULL, &ThreadAttr_CanRx);//cantx_taskThreadAttr_CanRx.stack_mem = mymalloc(THREAD_CANRX_SIZE);cantx_ids=osThreadNew(thread_canopen_tx, NULL, &ThreadAttr_CanTx);
}/*
*********************************************************************************************************
*   函 数 名: AppObjCreate
*   功能说明: 创建任务通信机制
*   形    参: 无
*   返 回 值: 无
*********************************************************************************************************
*/
static const osEventFlagsAttr_t EventFlagAttr_InitedAll= {.name = "InitedAll_Events",
};static const  osTimerAttr_t timerAttr_timer0 = {.name = "timer_0",
};
static const  osTimerAttr_t timerAttr_timer1 = {.name = "timer_1",
};
static const  osTimerAttr_t timerAttr_timer2 = {.name = "timer_2",
};
//软件定时器0中断回调函数
void timer0_callback(void *param)
{osSemaphoreRelease(sid_Semaphore_softtimer0);//100mSif(TimeOut){TimeOut--;}
}
//软件定时器1中断回调函数
void time1_callback(void *param)
{osSemaphoreRelease(sid_Semaphore_softtimer1);
}
//软件定时器2中断回调函数
void timer2_callback(void *param)
{osSemaphoreRelease(sid_Semaphore_softtimer2);
}/*----------------------------------------------------------------------------
Initilise Can1Tx_messageque*---------------------------------------------------------------------------*/
static  osMessageQueueAttr_t QueMessageAttr_Can1Tx={.name = "TxMessageQue",.mq_size = QUE_MESSAGE_COM_SIZE,//.mq_mem = NULL,
};
/*----------------------------------------------------------------------------
Initilise Can1Rx_messageque*---------------------------------------------------------------------------*/
static  osMessageQueueAttr_t QueMessageAttr_Can1Rx={.name = "RxMessageQue",.mq_size = QUE_MESSAGE_COM_SIZE,//.mq_mem = NULL,
};/*----------------------------------------------------------------------------*      Message Queue creation & usage*      Initilise the LED's, Create the semaphore *---------------------------------------------------------------------------*/
int AppObjCreate (void)
{/*timer*/timer0_id = osTimerNew(&timer0_callback, osTimerPeriodic,(void *)0, &timerAttr_timer0);  //软件定时器timer0 200msif (timer0_id == NULL){return -1;}timer1_id = osTimerNew(&time1_callback, osTimerPeriodic,(void *)0, &timerAttr_timer1);  //软件定时器timer1 1Sif (timer1_id == NULL){return -1;}timer2_id = osTimerNew(&timer2_callback, osTimerPeriodic,(void *)0, &timerAttr_timer2);    //软件定时器timer2 1Sif (timer2_id == NULL){return -1;}osTimerStart(timer0_id, 100);//启动系统软件定时器/*semaphore*/sid_Semaphore_softtimer0 = osSemaphoreNew(1, 0, NULL );if(sid_Semaphore_softtimer0 == NULL){return -1;}sid_Semaphore_softtimer1 = osSemaphoreNew(1, 0, NULL ); if(sid_Semaphore_softtimer1 == NULL){return -1;}sid_Semaphore_softtimer2 = osSemaphoreNew(1, 0, NULL );  if(sid_Semaphore_softtimer2 == NULL){return -1;}/*queue*/mid_MsgQueue_Set_temperature = osMessageQueueNew(msgQUEUE_ITEM,sizeof(temp_set_t), NULL);if (mid_MsgQueue_Set_temperature == NULL) {return -1;}mid_MsgQueue_usart1_rx = osMessageQueueNew(can_Rx_frame_item,sizeof(loopData_Typedef), NULL); //深度can_Rx_frame_itemif (mid_MsgQueue_usart1_rx == NULL) {return -1;} //feedbackmid_MsgQueue_feedbak_temperature = osMessageQueueNew(msgQUEUE_ITEM,sizeof(fb_TEMP_t), NULL);if (mid_MsgQueue_feedbak_temperature == NULL) {return -1; // Message Queue object not created, handle failure}//flash 升级接受数据使用mid_MsgQueue_usart1_rx_falshupdata = osMessageQueueNew(falshUpdata_Rx_frame_item,sizeof(loopData_Typedef), NULL);if (falshUpdata_Rx_frame_item == NULL) {return -1;}  /*event*/mid_event_Inited = osEventFlagsNew  (&EventFlagAttr_InitedAll);//所有初始化完成//通讯QueMessageAttr_Can1Tx.mq_mem = mymalloc(QUE_MESSAGE_COM_SIZE);osMQId_Can1Tx = osMessageQueueNew(msgQUEUE_ITEM,256, &QueMessageAttr_Can1Tx);if (osMQId_Can1Tx == NULL) {return -1;}QueMessageAttr_Can1Rx.mq_mem = mymalloc(QUE_MESSAGE_COM_SIZE);osMQId_Can1Rx = osMessageQueueNew(msgQUEUE_ITEM,256, &QueMessageAttr_Can1Rx);if (osMQId_Can1Rx == NULL) {return -1;}  return (0);
}uint8_t *p_test;
void app_main (void const* arg)
{//  osStatus_t status;/* 创建任务通信机制 */AppObjCreate();/* 创建任务 */AppTaskCreate();#ifdef SDRAM_TESTp_test=mymalloc(SRAMEX,THREAD_MAIN_SIZE);for(uint16_t i=0;i<2048;i++)*(p_test+i)=i;__NOP();myfree(SRAMEX,p_test);p_test=mymalloc(SRAMEX,20);#endifwhile(1) {        if(TimeOut==0){TimeOut=2;LED_RUN_Toggle();}  }}

app_main.h

#ifndef __APP_MAIN_H__
#define __APP_MAIN_H__
#include "cmsis_os2.h"               #define msgQUEUE_ITEM  5#define falshUpdata_Rx_frame_len       1024         /* 数据帧长度 */
#define falshUpdata_Rx_frame_item      4           /* 数据帧条数 */
#define falshUpdata_FRAME_MAX_SIZE    (falshUpdata_Rx_frame_len*falshUpdata_Rx_frame_item)  /*需要开辟在缓冲区4K Byte数*/#define can_Rx_frame_len       8             /* 数据帧长度 */
#define can_Rx_frame_item      50            /* 数据帧条数 */
#define can_FRAME_MAX_SIZE    (can_Rx_frame_len*can_Rx_frame_item)  /*需要开辟在缓冲区400Byte数*//*
分配线程堆栈空间大小
*/
#define QUE_MESSAGE_COM_SIZE    1024
#define THREAD_MAIN_SIZE            2048
#define THREAD_LED_SIZE       2048
#define THREAD_CANTX_SIZE       2048
#define THREAD_CANRX_SIZE       2048
typedef struct
{uint16_t addr;uint16_t en;uint16_t  temp;
}temp_set_t;typedef struct{uint16_t  time;uint16_t  temperature_PE;uint16_t  temperature_FAN;uint16_t  work_status;uint16_t  error;
}fb_TEMP_t;/*semaphore*/
extern  osSemaphoreId_t     sid_Semaphore_softtimer0;
extern  osSemaphoreId_t     sid_Semaphore_softtimer1;
extern  osSemaphoreId_t     sid_Semaphore_softtimer2;
/*queue*/
extern  osMessageQueueId_t  mid_MsgQueue_usart1_rx;
extern  osMessageQueueId_t  mid_MsgQueue_feedbak_temperature;
extern  osMessageQueueId_t  mid_MsgQueue_Set_temperature;
extern  osMessageQueueId_t  mid_MsgQueue_usart1_rx_falshupdata;
extern  osMessageQueueId_t  osMQId_Can1Tx;
extern  osMessageQueueId_t  osMQId_Can1Rx;
/*event*/
//extern    osEventFlagsId_t    mid_event_Inited;
/*timer*/
extern  osTimerId_t     timer0_id;//200ms 定时器PID计算
extern  osTimerId_t     timer1_id;//1S 显示时间
extern  osTimerId_t     timer2_id;
/* 供外部调用的函数声明 */
static void AppTaskCreate (void);
int  AppObjCreate (void);#endif

main_thread.c

#include  "main_thread.h"
void main_task (void * arg)
{while(1){osDelay(1);osThreadYield();}
}

main_thread.h

#ifndef __MAIN_THREAD_H
#define __MAIN_THREAD_H
#include "stm32f4xx_hal.h"
#include "cmsis_os2.h"
#include "app_main.h"
void main_task (void * arg);#endif

bsp_sdram.c

#include "bsp_sdram.h"
#include "sys.h"
#include "fmc.h"
#include "delay.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//SDRAM驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
////发送SDRAM初始化序列
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{u32 temp=0;//SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAMSDRAM_Send_Cmd(0,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能Delay_Us(500);
//    HAL_Delay(1000);                                  //至少延时200usSDRAM_Send_Cmd(0,FMC_SDRAM_CMD_PALL,1,0);       //对所有存储区预充电SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_AUTOREFRESH_MODE,8,0);//设置自刷新次数 //配置模式寄存器,SDRAM的bit0~bit2为指定突发访问的长度,//bit3为指定突发访问的类型,bit4~bit6为CAS值,bit7和bit8为运行模式//bit9为指定的写突发模式,bit10和bit11位保留位temp=(u32)SDRAM_MODEREG_BURST_LENGTH_1          |    //设置突发长度:1(可以是1/2/4/8)SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL   |   //设置突发类型:连续(可以是连续/交错)SDRAM_MODEREG_CAS_LATENCY_3           |    //设置CAS值:3(可以是2/3)SDRAM_MODEREG_OPERATING_MODE_STANDARD |   //设置操作模式:0,标准模式SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;     //设置突发写模式:1,单点访问SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_LOAD_MODE,1,temp);   //设置SDRAM的模式寄存器//刷新频率计数器(以SDCLK频率计数),计算方法://COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数//我们使用的SDRAM刷新周期为64ms,SDCLK=180/2=90Mhz,行数为8192(2^13).//所以,COUNT=64*1000*90/8192-20=683HAL_SDRAM_ProgramRefreshRate(&hsdram1,683);}//向SDRAM发送命令
//bankx:0,向BANK5上面的SDRAM发送指令
//      1,向BANK6上面的SDRAM发送指令
//cmd:指令(0,正常模式/1,时钟配置使能/2,预充电所有存储区/3,自动刷新/4,加载模式寄存器/5,自刷新/6,掉电)
//refresh:自刷新次数
//regval:模式寄存器的定义
//返回值:0,正常;1,失败.
u8 SDRAM_Send_Cmd(u8 bankx,u8 cmd,u8 refresh,u16 regval)
{u32 target_bank=0;FMC_SDRAM_CommandTypeDef Command;if(bankx==0) target_bank=FMC_SDRAM_CMD_TARGET_BANK1;       else if(bankx==1) target_bank=FMC_SDRAM_CMD_TARGET_BANK2;   Command.CommandMode=cmd;                //命令Command.CommandTarget=target_bank;      //目标SDRAM存储区域Command.AutoRefreshNumber=refresh;      //自刷新次数Command.ModeRegisterDefinition=regval;  //要写入模式寄存器的值if(HAL_SDRAM_SendCommand(&hsdram1,&Command,0X1000)==HAL_OK) //向SDRAM发送命令{return 0;  }else return 1;
}//在指定地址(WriteAddr+Bank5_SDRAM_ADDR)开始,连续写入n个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FMC_SDRAM_WriteBuffer(u8 *pBuffer,u32 WriteAddr,u32 n)
{for(;n!=0;n--){*(vu8*)(Bank5_SDRAM_ADDR+WriteAddr)=*pBuffer;WriteAddr++;pBuffer++;}
}//在指定地址((WriteAddr+Bank5_SDRAM_ADDR))开始,连续读出n个字节.
//pBuffer:字节指针
//ReadAddr:要读出的起始地址
//n:要写入的字节数
void FMC_SDRAM_ReadBuffer(u8 *pBuffer,u32 ReadAddr,u32 n)
{for(;n!=0;n--){*pBuffer++=*(vu8*)(Bank5_SDRAM_ADDR+ReadAddr);ReadAddr++;}
}

bsp_sdram.h

#ifndef _SDRAM_H_
#define _SDRAM_H_
#include "sys.h"
#include "stm32f4xx_hal.h"
#include "fmc.h"
#ifndef _SDRAM_H
#define _SDRAM_H//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F429开发板
//SDRAM驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/1/6
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//  #define Bank5_SDRAM_ADDR    ((u32)(0XC0000000)) //SDRAM开始地址//SDRAM配置参数
#define SDRAM_MODEREG_BURST_LENGTH_1             ((u16)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2             ((u16)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4             ((u16)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8             ((u16)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL      ((u16)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED     ((u16)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2              ((u16)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3              ((u16)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD    ((u16)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((u16)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE     ((u16)0x0200)void SDRAM_MPU_Config(void);
u8 SDRAM_Send_Cmd(u8 bankx,u8 cmd,u8 refresh,u16 regval);
void FMC_SDRAM_WriteBuffer(u8 *pBuffer,u32 WriteAddr,u32 n);
void FMC_SDRAM_ReadBuffer(u8 *pBuffer,u32 ReadAddr,u32 n);
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram);
#endif#endif

bsp_can.h

#ifndef _BSP_CAN_H
#define _BSP_CAN_H#include "main.h"
#define CANOPEN_TIM_PERIOD 100typedef struct
{CAN_TxHeaderTypeDef Header;uint8_t Data[8];
}CanTxMsg_t;
typedef struct
{CAN_RxHeaderTypeDef Header;uint8_t Data[8];
}CanRxMsg_t;#endif

canopen_drv.c

#include "canopen_drv.h"
#include "DPCRMaster.h"
#include "bsp_can.h"
#include "tim.h"
#include "can.h"
#include "app_main.h"CanTxMsg_t CAN1_TxMsg;
CanRxMsg_t CAN1_RxMsg;
uint32_t TxMailbox = CAN_TX_MAILBOX1;/*定时器相关变量*/
static TIMEVAL laster_counter_val = 0;
static TIMEVAL elapsed_time = 0;void thread_canopen_rx(void *arg)
{static CanRxMsg_t CAN1_RxMsg;static Message msg;uint8_t i=0;while(1){if(osOK == osMessageQueueGet(osMQId_Can1Rx,&CAN1_RxMsg,NULL,100))//从can接收消息队列中获取内容{msg.cob_id = CAN1_RxMsg.Header.StdId;if(CAN_RTR_REMOTE == CAN1_RxMsg.Header.RTR)msg.rtr = 1;//远程帧elsemsg.rtr = 0;//数据帧msg.len = (UNS8)CAN1_RxMsg.Header.DLC;for(i=0;i<CAN1_RxMsg.Header.DLC;i++){msg.data[i] = CAN1_RxMsg.Data[i];}__HAL_TIM_DISABLE_IT(&htim_can,TIM_IT_UPDATE);canDispatch(&DPCRMaster_Data,&msg);//调用协议相关接口__HAL_TIM_DISABLE_IT(&htim_can,TIM_IT_UPDATE);}osDelay(1);}
}void thread_canopen_tx(void *arg)
{unsigned char nodeID=0x01;HAL_TIM_Base_Start(&htim_can);setNodeId(&DPCRMaster_Data,nodeID);//节点初始化setState(&DPCRMaster_Data,Initialisation);setState(&DPCRMaster_Data,Operational);while(1){if(osOK == osMessageQueueGet(osMQId_Can1Tx,&CAN1_TxMsg,NULL,100)){if(HAL_OK != HAL_CAN_AddTxMessage(&hcan1,&CAN1_TxMsg.Header,CAN1_TxMsg.Data,&TxMailbox)){osDelay(1);HAL_CAN_AddTxMessage(&hcan1,&CAN1_TxMsg.Header,CAN1_TxMsg.Data,&TxMailbox);}}osDelay(1);}
}//
unsigned char canSend(CAN_PORT notused,Message *m)
{uint8_t i;static CanTxMsg_t TxMsg;TxMsg.Header.StdId = m->cob_id;if(m->rtr)TxMsg.Header.RTR = CAN_RTR_REMOTE;elseTxMsg.Header.RTR = CAN_RTR_DATA;TxMsg.Header.IDE = CAN_ID_STD;TxMsg.Header.DLC = m->len;for(i=0;i<m->len;i++)TxMsg.Data[i]=m->data[i];if(osOK == osMessageQueueGet(osMQId_Can1Tx,&TxMsg,NULL,NULL)){return 0;}else{return 0xFF;}
}void setTimer(TIMEVAL value)
{uint32_t timer = __HAL_TIM_GetCounter(&htim_can); elapsed_time +=timer-laster_counter_val;laster_counter_val = CANOPEN_TIM_PERIOD - value;__HAL_TIM_SetCounter(&htim_can,CANOPEN_TIM_PERIOD - value);HAL_TIM_Base_Start(&htim_can);//TIM_Cmd(CANOPEN_TIMx,ENABLE);
}TIMEVAL getElapsedTime(void)
{uint32_t timer = __HAL_TIM_GetCounter(&htim_can);if(timer < laster_counter_val)timer += CANOPEN_TIM_PERIOD;TIMEVAL elapsed = timer - laster_counter_val + elapsed_time;return elapsed;
}void CanOpen_DispatchFromISR(void)
{laster_counter_val = 0;elapsed_time = 0;TimeDispatch();
}//定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(&htim_can == htim){CanOpen_DispatchFromISR();}
}
//CAN接收回调
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{if(hcan == &hcan1)//接收中断里把收到的数据放入消息队列中{HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&CAN1_RxMsg.Header,CAN1_RxMsg.Data);if(osOK == osMessageQueuePut(osMQId_Can1Rx,&CAN1_RxMsg,NULL,NULL)){;}else{Error_Handler();}}
}

canopen_drv.h

#ifndef _CANOPEN_DRV_H
#define _CANOPEN_DRV_H
#include "stm32f4xx_hal.h"
#include "cmsis_os2.h"
#include "app_main.h"void thread_canopen_rx(void *arg);
void thread_canopen_tx(void *arg);#endif

A板----------------相关推荐

  1. zeroclipboard 粘贴板的应用示例, 兼容 Chrome、IE等多浏览器

    zeroclipboard单个复制按钮和多个复制按钮的实现方法 最近网站改版想让复制代码功能在多个浏览器上都可以实现,最近看网上不少说我们的代码复制功能不好用的,我们最近将会增加代码高亮等功能,希望大 ...

  2. 2022-2028年中国中密度纤维板市场投资分析及前景预测报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了中密度纤维板行业相关概述.中国中密度纤维板行业运行环境.分析了中国中 ...

  3. 2022-2028年中国塑料板的制造行业市场发展模式及竞争格局预测报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了塑料板的制造行业相关概述.中国塑料板的制造行业运行环境.分析了中国塑 ...

  4. 2022-2028年中国硅酸钙板行业市场研究及前瞻分析报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了硅酸钙板行业相关概述.中国硅酸钙板行业运行环境.分析了中国硅酸钙板行 ...

  5. 2022-2028年中国XPS挤塑板行业市场全景评估及产业前景规划报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了XPS挤塑板行业相关概述.中国XPS挤塑板行业运行环境.分析了中国X ...

  6. 编写可调模板并使用自动调谐器

    编写可调模板并使用自动调谐器 这是TVM中自动调整模块的入门资料. 自动调整有两个步骤.第一步是定义搜索空间.第二步是运行搜索算法来探索这个空间.在本文中,可以学习如何在TVM中执行这两个步骤.整个工 ...

  7. 编写可调模板并使用Auto-tuner自动调谐器

    编写可调模板并使用Auto-tuner自动调谐器 本文介绍在TVM自动调谐模块. 自动调谐有两个步骤.第一步是定义搜索空间.第二步是运行一个搜索算法来探索这个空间.可以学习如何在TVM中执行这两个步骤 ...

  8. Xilinx Zynq FPGA Boards板

    Xilinx Zynq FPGA Boards板 Xilinx Zynq FPGA Boards 介绍 Styx是一个易于使用的Zynq开发模块,具有Xilinx的Zynq ZC7020 SoC和FT ...

  9. 基于uFUN开发板的心率计(一)DMA方式获取传感器数据

    前言 从3月8号收到板子,到今天算起来,uFUN到手也有两周的时间了,最近利用下班后的时间,做了个心率计,从单片机程序到上位机开发,到现在为止完成的差不多了,实现很简单,uFUN开发板外加一个Puls ...

  10. 2022-2028年中国塑料网格板行业市场行情动态及发展趋向分析报告

    [报告类型]产业研究 [出版时间]即时更新(交付时间约3个工作日) [发布机构]智研瞻产业研究院 [报告格式]PDF版 本报告介绍了塑料网格板行业相关概述.中国塑料网格板行业运行环境.分析了中国塑料网 ...

最新文章

  1. Python装饰器-装饰流程,执行顺序
  2. 基于python的界面自动化测试-基于Selenium+Python的web自动化测试框架
  3. Boost:双图bimap与mi_bidirectional地图的测试程序
  4. HDU4514(非连通图的环判断与图中最长链)
  5. [CSS] Use CSS Counters to Create Pure CSS Dynamic Lists
  6. 【CF1200E】Compress Words【kmp】
  7. JVM参数设置、分析
  8. python绘画梦想_用python实现你的绘画梦想
  9. 使用 Jupyter 近 2 年,发现了这 3 个实用技巧
  10. 用 C# 实现带键值的优先队列
  11. 数据结构笔记(十五)-- 数组原理
  12. EXCEL 2010学习笔记—— 动态图表
  13. Vijos P1423 最佳路线
  14. 联发科MT7621 Openwrt开发编译记录
  15. 51单片机之定时器/计数器0中断程序
  16. 计算机显卡型号中数字含义详解,显卡型号中字母和数字所代表的含义
  17. dejavu项目笔记
  18. 实战技法 - 短线操盘 (8)
  19. jupyter notebook 的 hinterland 插件 设置 代码提示但是默认不选中
  20. mysql 权限管理 针对表的字段 级别 授权 columns_priv表

热门文章

  1. 线性表顺序存储结构的基本实现
  2. SpringCloud 学习笔记(1 / 3)
  3. lightoj 1018 - Brush (IV)
  4. WorkStation创建linux虚拟机
  5. Unity基本操作学习
  6. 总离差平方和公式_在多元线性回归模型中,回归平方和与总离差平方和的比值称为( )_学小易找答案...
  7. 设计模式-代理模式 C++
  8. 基于VUE和JSPlumb的在线绘制流程图工具
  9. 安卓手机怎么卸载APP软件
  10. Unity基本操作汇总