STM32F107加载UCOS系统并实现CAN总线通信

一、系统架构设计

  1. 核心模块组成

    • UCOS实时操作系统:负责多任务调度、信号量管理、中断服务

    • CAN通信模块:STM32内置CAN控制器 + 中断接收处理

    • 硬件外设:LED指示灯、按键输入(用于任务状态调试)

  2. 开发环境配置

    • IDE:Keil MDK-ARM 5.34

    • 芯片型号:STM32F107VCT6(Cortex-M3内核,72MHz主频)

    • 协议栈:STM32 HAL库 + UCOS-II源码(官方移植版本)


二、UCOS系统移植步骤

1. 移植文件准备
  • 获取源码:从Micrium官网下载UCOS-II 2.92源码,提取以下文件:

    ucos_ii.h          // 核心头文件
    os_core.c          // 内核调度核心
    os_task.c          // 任务管理
    os_mem.c           // 内存管理
    os_time.c          // 时间管理
    
  • 硬件适配文件

    os_cpu.h           // CPU类型定义
    os_cpu_a.asm       // 汇编启动代码
    os_cpu_c.c         // C语言接口
    
2. 工程配置
  • 新建工程:在Keil中创建STM32F107工程,添加以下目录:

    /Src
      ├─ Core/         // UCOS核心文件
      ├─ Drivers/      // HAL库驱动
      └─ Apps/         // 应用层代码
    
  • 头文件路径:添加os_cpu.hstm32f10x.h等路径

3. 关键代码实现
  • 系统初始化main.c):

    #include "stm32f10x.h"
    #include "os.h"
    
    OS_STK TaskStartStk[128];  // 启动任务堆栈
    OS_EVENT *CanSem;          // CAN接收信号量
    
    void main(void) {
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
      SystemInit();                                    // 系统时钟初始化
    
      // 创建启动任务
      OSTaskCreate(TaskStart, (void*)0, &TaskStartStk[0], 10);
    
      OSStart();  // 启动UCOS调度
    }
    
  • 启动任务task_start.c):

    void TaskStart(void *p_arg) {
      OS_CPU_SR cpu_sr;
    
      // 初始化CAN硬件
      CAN_Configuration();
    
      // 创建信号量
      CanSem = OSSemCreate(0);
    
      // 创建CAN接收任务
      OSTaskCreate(CAN_RecvTask, (void*)0, &TaskStartStk[32], 15);
    
      while(1) {
        OSSemPend(CanSem, OS_TICKS_PER_SEC, &cpu_sr);  // 等待CAN中断信号
        // 处理接收到的数据
      }
    }
    

三、CAN总线通信实现

1. CAN硬件配置
  • GPIO与时钟配置

    void CAN_GPIO_Config(void) {
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    
      GPIO_InitTypeDef GPIO_InitStruct;
      GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
      GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  // RX上拉
      GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
    
  • CAN控制器初始化

    void CAN_Configuration(void) {
      CAN_InitTypeDef CAN_InitStructure;
    
      CAN_DeInit(CAN1);  // 复位CAN模块
      CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;    // 正常模式
      CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;         // 同步跳跃宽度
      CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq;         // 时间段1
      CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;         // 时间段2
      CAN_InitStructure.CAN_Prescaler = 5;             // 分频系数(500kbps)
      CAN_Init(CAN1, &CAN_InitStructure);
    }
    
2. CAN中断与消息处理
  • 中断配置

    void CAN_NVIC_Config(void) {
      NVIC_InitTypeDef NVIC_InitStruct;
      NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQn;  // CAN接收中断
      NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
      NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
      NVIC_EnableIRQ(NVIC_InitStruct.NVIC_IRQChannel);
    }
    
  • 中断服务函数

    void USB_LP_CAN_RX0_IRQHandler(void) {
      OSIntEnter();  // 进入中断临界区
      CanRxMsg RxMessage;
      CAN_Receive(CAN1, CAN_Filter_FIFO0, &RxMessage);  // 接收消息
    
      // 发送信号量通知任务
      OSSemPost(CanSem);
    
      OSIntExit();  // 退出中断临界区
    }
    

参考代码 STM32f107加载ucos系统,实现CAN总线通信 www.youwenfan.com/contentcnr/101916.html

四、多任务协同设计

1. 任务优先级分配
任务名称 优先级 功能描述
CAN_RecvTask 15 处理接收到的CAN数据
LED_Task 20 控制LED状态(调试用)
DataProcessTask 25 数据解析与存储
2. 任务间通信
  • 消息队列(用于传递CAN数据):

    #define CAN_QUEUE_LEN  10
    OS_EVENT *CanQueue;
    
    void main() {
      CanQueue = OSQCreate(CAN_MsgBuffer, CAN_QUEUE_LEN);
    }
    
    // 发送任务
    void SendDataTask(void *p_arg) {
      CanTxMsg TxMessage = {0x123, 8, 0};
      OSQPost(CanQueue, &TxMessage);  // 发送消息到队列
    }
    

通过上述方案,可在STM32F107上实现UCOS实时操作系统CAN总线通信的深度集成,满足工业控制场景下的实时性要求。

posted @ 2026-03-01 11:12  风一直那个吹  阅读(2)  评论(0)    收藏  举报