STM32 CAN总线说明

2023-05-16

简介:

  1. CAN是Controller Area Network 的缩写(以下称为CAN),是ISO国际标准化的串行通信协议。由德国电气商博世公司在1986年率先提出。此后,CAN通过ISO11898及ISO11519进行了标准化。现在在欧洲已是汽车网络的标准协议。
  2. CAN协议经过ISO标准化后有两个标准:ISO11898标准和ISO11519-2标准。其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准,而ISO11519-2是针对通信速率为125Kbps以下的低速通信标准。
  3. CAN具有很高的可靠性,广泛应用于:汽车电子、工业自动化、船舶、医疗设备、工业设备等方面。

特点:

  1. 多主控制。总线空闲时,所有单元都可发送消息,而两个以上的单元同时开始发送消息时,根据标识符(ID,非地址)决定优先级。两个以上的单元同时开始发送消息时,对各消息ID 的每个位进行逐个仲裁比较。仲裁获胜(优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。
  2. 系统柔软性。连接总线的单元,没有类似“地址”的信息,因此,在总线上添加单元时,已连接的其他单元的软硬件和应用层都不需要做改变。
  3. 速度快,距离远。最高1Mbps(距离<40M),最远可达10KM(速率<5Kbps)。
  4. 具有错误检测、错误通知和错误恢复功能。所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。
  5. 故障封闭功能。CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。
  6. 连接节点多。CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。

物理特征:

总线电平=CAN_H的电压-CAN_L的电压
显性电平对应逻辑0=总线电平为2V左右
隐性电平对应逻辑0=总线电平为0V
这里写图片描述

显性电平具有优先权,只要有一个单元输出显性电平,总线上即为显性电平。而隐形电平则具有包容的意味,只有所有的单元都输出隐性电平,总线上才为隐性电平(显性电平比隐性电平更强)。另外,在CAN总线的起止端都有一个120Ω的终端电阻,来做阻抗匹配,以减少回波反射。

帧种类介绍:

帧种类帧作用
数据帧用于发送单元向接收单元传送数据的帧
遥控帧用于接收单元向具有相同 ID 的发送单元请求数据的帧
错误帧用于当检测出错误时向其它单元通知错误的帧
过载帧用于接收单元通知其尚未做好接收准备的帧
间隔帧用于将数据帧及遥控帧与前面的帧分离开来的帧

注:其中,数据帧和遥控帧有标准格式和扩展格式两种格式。
标准格式有11 个位的标识符(ID),扩展格式有29 个位的ID 。

STM32 CAN控制器简介:

  1. 支持CAN协议2.0A和2.0B主动模式
  2. 波特率最高达1Mbps
  3. 支持时间触发通信
  4. 具有3个发送邮箱
  5. 具有3级深度的2个接收FIFO
  6. 可变的筛选器组(也称过滤器组,最多28个,F1普通为14个,互联和F4为28个,另外F4有两个can,F1只有一个)

3种模式:
工作模式:

  • 初始化模式(INRQ=1,SLEEP=0)
  • 正常模式(INRQ=0,SLEEP=0)
  • 睡眠模式(SLEEP=1)

测试模式:

  • 静默模式( LBKM=0,SILM=1 )
  • 环回模式( LBKM=1,SILM=0 )
  • 环回静默模式(LBKM=1,SILM=1)

调试模式(不常用)

STM32 CAN筛选器位宽和模式配置:

CAN的标识符不表示目的地址而是表示发送优先级,接收节点根据标识符的值,来决定是否接收对应消息。
这里写图片描述

标识符屏蔽模式:过滤一组标识符
标识符列表模式:过滤一个标识符

例:设置筛选器组0工作在:1个32位筛选器-标识符屏蔽模式,然后设置CAN_F0R1=0XFFFF0000,CAN_F0R2=0XFF00FF00。其中存放到CAN_F0R1的值就是期望收到的ID,即(STID+EXTID+IDE+RTR)最好是:0XFFFF0000。而0XFF00FF00就是设置我们需要必须关心的ID,表示收到的映像,其位[31:24]和位[15:8]这16个位的必须和CAN_F0R1中对应的位一模一样,而另外的16个位则不关心,可以一样,也可以不一样,都认为是正确的ID,即收到的映像必须是0XFFxx00xx,才算是正确的(x表示不关心)。

波特率设置:

TM32F103,设TS1=8、TS2=7、BRP=3,波特率=36000/[(9+8+1)*4]=500Kbps。

STM32F407,设TS1=6、TS2=5、BRP=5,波特率=42000/[(7+6+1)*6]=500Kbps。

寄存器:

CAN主控制寄存器(CAN_MCR)

该寄存器的我们仅介绍下INRQ位,该位用来控制初始化请求。
设置INRQ=0,可使CAN从初始化模式进入正常工作模式。
设置INRQ=1,可使CAN从正常工作模式进入初始化模式。
CAN初始化时,先设置INRQ=1,进入初始化模式,进行初始化(尤其是CAN_BTR的设置,该寄存器,必须在CAN正常工作之前设置),之后再设置INRQ=0,进入正常工作模式。

CAN位时序寄存器(CAN_BTR)设置波特率
CAN接收FIFO寄存器(CAN_RF0R/CAN_RF1R)
CAN发送邮箱标识符寄存器(CAN_TIxR)(x=0~2)
CAN发送邮箱数据长度和时间戳寄存器 (CAN_TDTxR) (x=0~2)
低4位用于设置发送多少个字节,最多为8个字节
CAN发送邮箱数据寄存器(CAN_TDLxR/CAN_TDHxR) (x=0~2)
CAN接收FIFO邮箱标识符寄存器(CAN_RIxR)(x=0/1)
CAN接收FIFO邮箱数据长度和时间戳寄存器(CAN_RDTxR) (x=0/1)
CAN接收FIFO邮箱邮箱数据寄存器(CAN_RDLxR/CAN_RDHxR) (x=0/1)
CAN筛选器模式寄存器(CAN_FM1R)(0标识符屏蔽,1标识符列表)
CAN筛选器尺度寄存器(CAN_FS1R)(0双16位,1单32位)
CAN筛选器FIFO关联寄存器(CAN_FFA1R)(0筛选器分到FIFO0,1筛选器分到FIFO1)
CAN筛选器激活寄存器(CAN_FA1R)(0未激活,1激活)
CAN筛选器组i寄存器x(CAN_FiRx)(i=0~27,x=1/2)(F103筛选器只有14个)

配置步骤:

①配置相关引脚的 复用功能,使能CAN时钟。

N的时钟通过APB1ENR的第25位来设置。其次要设置CAN的相关引脚为复用输出,这里我们需要设置PA11为上拉输入(CAN_RX引脚)PA12为复用输出(CAN_TX引脚),并使能PA口的时钟(CAN_TX引脚),并使能PA口的时钟

②设置CAN工作模式及波特率等。

通过先设置CAN_MCR寄存器的INRQ位,让CAN进入初始化模式,然后设置CAN_MCR的其他相关控制位。再通过CAN_BTR设置波特率和工作模式(正常模式/环回模式)等信息。 最后设置INRQ为0,退出初始化模式。

③设置滤波器。

本例程,我们将使用筛选器组0,并工作在32位标识符屏蔽位模式下。先设置CAN_FMR的FINIT位,进入初始化模式,然后设置筛选器组0的工作模式以及标识符ID和屏蔽位。最后激活筛选器,并退出初始化模式。

CODE:

//can.c
#include "can.h"
#include "led.h"
#include "delay.h"
#include "usart.h" 

//CAN初始化
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024;  tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为36M,如果设置CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);
//则波特率为:36M/((8+9+1)*4)=500Kbps
//返回值:0,初始化OK;
//    其他,初始化失败; 
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{ 
    GPIO_InitTypeDef        GPIO_InitStructure; 
    CAN_InitTypeDef         CAN_InitStructure;
    CAN_FilterInitTypeDef   CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE 
    NVIC_InitTypeDef        NVIC_InitStructure;
#endif

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PORTA时钟                                                                
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);    //使能CAN1时钟  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);                  //初始化IO
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       //上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                  //初始化IO
    //CAN单元设置
    CAN_InitStructure.CAN_TTCM=DISABLE;         //非时间触发通信模式  
    CAN_InitStructure.CAN_ABOM=DISABLE;         //软件自动离线管理   
    CAN_InitStructure.CAN_AWUM=DISABLE;         //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN_InitStructure.CAN_NART=ENABLE;          //禁止报文自动传送 
    CAN_InitStructure.CAN_RFLM=DISABLE;         //报文不锁定,新的覆盖旧的  
    CAN_InitStructure.CAN_TXFP=DISABLE;         //优先级由报文标识符决定 
    CAN_InitStructure.CAN_Mode= mode;          //模式设置: mode:0,普通模式;1,回环模式; 
    //设置波特率
    CAN_InitStructure.CAN_SJW=tsjw;             //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq    CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    CAN_InitStructure.CAN_BS1=tbs1;             //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
    CAN_InitStructure.CAN_BS2=tbs2;             //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~    CAN_BS2_8tq
    CAN_InitStructure.CAN_Prescaler=brp;        //分频系数(Fdiv)为brp+1  
    CAN_Init(CAN1, &CAN_InitStructure);         //初始化CAN1 

    CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器0
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;   //屏蔽位模式
    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;  //32位宽 
    CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;    //32位ID
    CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0
    CAN_FilterInit(&CAN_FilterInitStructure);           //滤波器初始化

#if CAN_RX0_INT_ENABLE 
    CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);              //FIFO0消息挂号中断允许.            

    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            // 次优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
#endif
    return 0;
}   

#if CAN_RX0_INT_ENABLE  //使能RX0中断
//中断服务函数                
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  CanRxMsg RxMessage;
    int i=0;
  CAN_Receive(CAN1, 0, &RxMessage);
    for(i=0;i<8;i++)
    printf("rxbuf[%d]:%d\r\n",i,RxMessage.Data[i]);
}
#endif

//can发送一组数据(固定格式:ID为0X12,标准帧,数据帧)   
//len:数据长度(最大为8)                     
//msg:数据指针,最大为8个字节.
//返回值:0,成功;
//       其他,失败;
u8 Can_Send_Msg(u8* msg,u8 len)
{   
    u8 mbox;
    u16 i=0;
    CanTxMsg TxMessage;
    TxMessage.StdId=0x12;           // 标准标识符 
    TxMessage.ExtId=0x12;           // 设置扩展标示符 
    TxMessage.IDE=CAN_Id_Standard;  // 标准帧
    TxMessage.RTR=CAN_RTR_Data;     // 数据帧
    TxMessage.DLC=len;              // 要发送的数据长度
    for(i=0;i<len;i++)
    TxMessage.Data[i]=msg[i];                     
    mbox= CAN_Transmit(CAN1, &TxMessage);   
    i=0; 
    while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; //等待发送结束
    if(i>=0XFFF)return 1;
    return 0;    
}
//can口接收数据查询
//buf:数据缓存区;     
//返回值:0,无数据被收到;
//       其他,接收的数据长度;
u8 Can_Receive_Msg(u8 *buf)
{                  
    u32 i;
    CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;     //没有接收到数据,直接退出 
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//读取数据 
    for(i=0;i<8;i++)
    buf[i]=RxMessage.Data[i];  
    return RxMessage.DLC;   
}


main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"   
#include "can.h" 

 int main(void)
 {   
        u8 key;
    u8 i=0,t=0;
    u8 cnt=0;
    u8 canbuf[8];
    u8 res;
    u8 mode=CAN_Mode_LoopBack;//CAN工作模式;CAN_Mode_Normal(0):普通模式,CAN_Mode_LoopBack(1):环回模式

    delay_init();            //延时函数初始化    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);      //串口初始化为115200
    LED_Init();             //初始化与LED连接的硬件接口
    LCD_Init();             //初始化LCD    
    KEY_Init();             //按键初始化         

    CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack);//CAN初始化环回模式,波特率500Kbps    

    POINT_COLOR=RED;//设置字体为红色 
    LCD_ShowString(60,50,200,16,16,"WarShip STM32");    
    LCD_ShowString(60,70,200,16,16,"CAN TEST"); 
    LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
    LCD_ShowString(60,110,200,16,16,"2015/1/15");
    LCD_ShowString(60,130,200,16,16,"LoopBack Mode");    
    LCD_ShowString(60,150,200,16,16,"KEY0:Send WK_UP:Mode");//显示提示信息        
    POINT_COLOR=BLUE;//设置字体为蓝色    
    LCD_ShowString(60,170,200,16,16,"Count:");          //显示当前计数值   
    LCD_ShowString(60,190,200,16,16,"Send Data:");      //提示发送的数据   
    LCD_ShowString(60,250,200,16,16,"Receive Data:");   //提示接收到的数据      
    while(1)
    {
        key=KEY_Scan(0);
        if(key==KEY0_PRES)//KEY0按下,发送一次数据
        {
            for(i=0;i<8;i++)
            {
                canbuf[i]=cnt+i;//填充发送缓冲区
                if(i<4)LCD_ShowxNum(60+i*32,210,canbuf[i],3,16,0X80);   //显示数据
                else LCD_ShowxNum(60+(i-4)*32,230,canbuf[i],3,16,0X80); //显示数据
            }
            res=Can_Send_Msg(canbuf,8);//发送8个字节 
            if(res)LCD_ShowString(60+80,190,200,16,16,"Failed");        //提示发送失败
            else LCD_ShowString(60+80,190,200,16,16,"OK    ");          //提示发送成功                                   
        }else if(key==WKUP_PRES)//WK_UP按下,改变CAN的工作模式
        {      
            mode=!mode;
            CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,mode);//CAN普通模式初始化, 波特率500Kbps 
            POINT_COLOR=RED;//设置字体为红色 
            if(mode==0)//普通模式,需要2个开发板
            {
                LCD_ShowString(60,130,200,16,16,"Nnormal Mode ");       
            }else //回环模式,一个开发板就可以测试了.
            {
                LCD_ShowString(60,130,200,16,16,"LoopBack Mode");
            }
            POINT_COLOR=BLUE;//设置字体为蓝色 
        }        
        key=Can_Receive_Msg(canbuf);
        if(key)//接收到有数据
        {           
            LCD_Fill(60,270,130,310,WHITE);//清除之前的显示
            for(i=0;i<key;i++)
            {                                       
                if(i<4)LCD_ShowxNum(60+i*32,270,canbuf[i],3,16,0X80);   //显示数据
                else LCD_ShowxNum(60+(i-4)*32,290,canbuf[i],3,16,0X80); //显示数据
            }
        }
        t++; 
        delay_ms(10);
        if(t==20)
        {
            LED0=!LED0;//提示系统正在运行   
            t=0;
            cnt++;
            LCD_ShowxNum(60+48,170,cnt,3,16,0X80);  //显示数据
        }          
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 CAN总线说明 的相关文章

  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 在 MCU 内部 FLASH 中从一个固件跳转到另一个固件

    我目前正在开发针对 STM32F030C8 的引导加载程序固件应用程序 我在分散文件中指定引导加载程序应用程序将占用主内存位置 0x08000000 到 0x08002FFF 扇区 0 到扇区 2 我还编写了一个主固件应用程序 存储在0x0
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 139-基于stm32单片机老人居家监护报警系统Proteus仿真+源程序

    资料编号 139 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 MQ4传感器 电位器模拟 MQ2传感器 电位器模拟 蜂鸣器 电机 制作一个基于stm32单片机老人居家监护报警系统Proteus仿真 2 通过MQ2传
  • 140-基于stm32单片机智能晾衣杆控制系统Proteus仿真+源程序

    资料编号 140 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 DHT11传感器 ds1302时钟 光敏传感器 蜂鸣器 LED灯 制作一个基于stm32单片机智能晾衣杆控制系统Proteus仿真 2 通过光敏传感器
  • 133-基于stm32单片机停车场车位管理系统Proteus仿真+源程序

    资料编号 133 一 功能介绍 1 采用stm32单片机 4位数码管 独立按键 制作一个基于stm32单片机停车场车位管理系统Proteus仿真 2 通过按键进行模拟车辆进出 并且通过程序计算出当前的剩余车位数量 3 将剩余的车位数量显示到
  • rt-thread studio中新建5.02版本报错

    先吐槽一下 rt thread studio出现BUG真多 好多时间都是在找BUG 但里面用好多控件还是挺好用的 真是又爱又恨 所以一般使用功能不多的话还是用keil多一点 创建5 02版本工程之后直接进行编译 直接会报下面这个错误 资源
  • HAL库学习

    CMSIS简介 CMSIS Cortex Microcontroller Software Interface Standard 微控制器软件接口标准 由ARM和其合作的芯片厂商 ST NXP 软件工具厂商 KEIL IAR 共同制定的标准
  • SHT10温湿度传感器——STM32驱动

    实验效果 硬件外观 接线 3 3V供电 IIC通讯 代码获取 查看下方 END
  • 跟着野火学FreeRTOS:第一段(任务定义,切换以及临界段)

    在裸机系统中 系统的主体就是 C P U CPU CP U 按照预先设定的程序逻辑在 m a i n
  • STM32的HAL中实现单按、长按和双按功能

    我正在尝试实现单击 双击和长按功能来执行不同的功能 到目前为止 我已经理解了单击和长按的逻辑 但我不知道如何检测双击 至于代码 我使用计数器实现了单击和长按 但代码仅停留在第一个 if 条件上 bool single press false
  • Freertos低功耗管理

    空闲任务中的低功耗Tickless处理 在整个系统运行得过程中 其中大部分时间都是在执行空闲任务的 空闲任务之所以执行 因为在系统中的其他任务处于阻塞或者被挂起时才会执行 因此可以将空闲任务的执行时间转换成低功耗模式 在其他任务解除阻塞而准
  • STM32H5 Nucleo-144 board开箱

    文章目录 开发板资料下载 目标 点亮LD1 绿 LD2 黄 和LD3 红 三个LED灯 开箱过程 博主使用的是STM32CubeMX配置生成代码 具体操作如下 打开STM32CubeMX File gt New project 选择开发板型
  • 特殊寄存器

    特殊寄存器 文章目录 前言 一 背景 二 2 1 2 2 总结 前言 前期疑问 STM32特殊寄存器到底是什么 特殊寄存器怎么查看和调试代码 本文目标 记录和理解特殊寄存器 一 背景 最近在看ucosIII文章是 里面提到特殊寄存器 这就进
  • systick定时器

    systick定时器 文章目录 前言 一 前期疑惑 二 解答 1 关于systick是阻塞的吗 2 非阻塞 三 软件编写 总结 前言 这边记录systick相关知识点 一 前期疑惑 在学习systick志气啊 其实对于systick还是一脸
  • STM32F0、ST-link v2、OpenOCD 0.9.0:打开失败

    我在用着发射台 http www ti com ww en launchpad about htmlgcc arm none eabi 4 9 2015q2 为 STM32F0 进行编译 现在我想使用该集合中的 arm none eabi
  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • 使用 STM32F0 ADC 单独读取不同的输入

    STM32F072CBU 微控制器 我有多个 ADC 输入 并且希望单独读取它们 STMcubeMX 生成样板代码 假设我希望按顺序读取所有输入 但我无法弄清楚如何纠正这个问题 这篇博文 http blog koepi info 2015
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一

随机推荐

  • Android应用安全检测工具简介

    Android应用安全检测工具简介 1 测试工具集 Appie 轻量级的软件包 可以用来进行基于Android的渗透测试 不想使用VM的时候可以尝试一下 Android Tamer 可以实时监控的虚拟环境 可以用来进行一系列的安全测试 恶意
  • C语言浮点型数据存储结构

    1 float类型 float类型占四个字节 xff0c 每个字节占8位 xff0c 总共32位 xff0c 其内存结构如下图 xff1a 31位为符号位 xff1a 0表示正数 xff0c 1表示负数 31 23位 xff1a 共8位表示
  • sockaddr和sockaddr_in详解

    struct sockaddr和struct sockaddr in这两个结构体用来处理网络通信的地址 一 sockaddr sockaddr在头文件 include lt sys socket h gt 中定义 xff0c sockadd
  • python requests模拟登陆带验证码的网站

    作为之前专利爬虫的续篇 xff0c 本篇准备描述如何通过python的requests模块登录专利查询网站 环境准备 python 3 6requests chrome尝试 首先 xff0c 我们使用chrome尝试登录专利网站 xff0c
  • 兔子与兔子(下一篇解释原理:字符串哈希)

    文章目录 兔子与兔子题目描述解题思路 兔子与兔子 题目描述 很久很久以前 xff0c 森林里住着一群兔子 有一天 xff0c 兔子们想要研究自己的 DNA 序列 我们首先选取一个好长好长的 DNA 序列 xff08 小兔子是外星生物 xff
  • 机器学习(二)--- KNN(K-Nearest Neighbors)

    KNN K Nearest Neighbors 简单类比 xff08 Simple Analogy xff09 KNN xff1a 通过你周围的人来判断你是哪一类人 Tell me about your friends who your n
  • 机器学习(三) --- DT(Decision Tree)

    文章目录 Decision TreeIntroductionConstructing Decision Treesexample Pruning决策树 随机森林和Gradient BoostingReference xff1a Decisi
  • 3D点云资料(笔记自用)

    数据集 xff1a Pointnet Pointnet2 pytorch Pointnet语义分割任务S3DIS数据集上的注意点 dataset ShapeNet简介及认识 文件格式 PCD格式 目标检测标注工具 标注工具windows安装
  • 用指针给数组赋值的一个小问题

    问题是这样的 xff0c 我打算输入与元素为数组赋值 xff0c 然后反向输出数组元素 include lt stdio h gt int main void int a 10 p 61 a i for i 61 0 i lt 10 i 4
  • 51之中断

    51单片机的中断系统 选用的单片机型号是 xff1a HC6800 ES V2 0 一 中断的概念 CPU在处理某一事件A时 xff0c 发生了另一事件B请求CPU迅速去处理 xff08 中断发生 xff09 xff1b CPU暂时中断当前
  • 基于51单片机和L298N的小车制作(一)

    到目前为止 xff0c 总算把51单片机过了一遍 xff0c 本来暑假就要完成的任务一直拖到了现在 51学完 xff0c 就想着先做点东西 xff0c 就从小车开始 玩小车最重要的是什么 xff1f 电机 这个就不用多解释了 从今天早上开始
  • 如何把android设备中的固件dump出来

    android固件是在mtdblock中 但是会有很多个block root 64 android cat proc partitions major minor blocks name 31 0 4096 mtdblock0 31 1 1
  • PID控制电机转速

    转一个PID控制电机的小程序 xff0c 被PID困扰好多天了 xff0c 知道它的原理但是一直不明白如何将它运用到电机调速中间去 xff0c 看了这个程序之后感觉茅塞顿开 原来也并不难 转载地址 xff1a 呃 xff0c 刚刚不小心把网
  • vs2017常用快捷键

    VS2017常用快快捷键 目录 43 VS常用快捷键搜集窗口操作快捷键项目快捷键调试快捷键编辑快捷键代码快捷键单元测试 xfeff xfeff 项目相关的快捷键 Ctrl 43 Shift 43 B 61 生成项目 Ctrl 43 Alt
  • phpStudy基本用法

    闲扯正文 更改目录更改首页更改端口号DNS解析 参考资料 闲扯 第一次接触php xff0c 要先安装环境 xff0c 包括Apache mySQL和PHP xff1b 安装就安装呗 xff0c 我先跑到Apache官网上面想下一个Apac
  • 小白学爬虫(三)-- requests库之Cookie

    前言使用超时参数在requests添加Cookie参数 啥是cookie三种Cookie请求方式 第一种 xff1a cookie放在headers中第二种 xff1a cookie字典传给cookies参数第三种 先发送post请求 xf
  • 操作系统(五) -- CPU的调度策略

    文章目录 常见的调度策略以及考虑的内容 CPU调度的直观想法 xff1a FIFOPriority xff08 优先级 xff09 如何评价一个调度算法的好坏 xff1f 上述三个指标之间是不是存在冲突呢 xff1f 前台任务和后台任务的关
  • vscode 前端最佳插件配置

    vscode最佳配置 最近更新时间 xff1a 2023 02 18 xff08 Vscode v1 17 xff09 vscode 配置文件内容在最后 xff0c 可直接copy使用 配置详解 editor是针对 vscode 的风格设置
  • Java序列化与反序列化及serialVersionUID

    Java序列化与反序列化是什么 xff1f 为什么需要序列化与反序列化 xff1f 如何实现Java序列化与反序列化 xff1f 本文围绕这些问题进行了探讨 1 Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程
  • STM32 CAN总线说明

    简介 xff1a CAN是Controller Area Network 的缩写 xff08 以下称为CAN xff09 xff0c 是ISO国际标准化的串行通信协议 由德国电气商博世公司在1986年率先提出 此后 xff0c CAN通过I