stm32迁移

stm32迁移

首先从C51 迁移到 == stm32== 会有部分代码不一样,主要就是stm32所有的初始状态需要自己初始化

位带

位带方便易于迁移,因为stm32没有sbit定义的方式

位带初始化函数,主要用于IO口

c 复制代码
#ifndef _system_H
#define _system_H
#include "stm32f10x.h"
//位带操作,实现 51 类似的 GPIO 控制功能
//IO 口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr & 0xFFFFF)<<5)+(bitnum<<2))
    
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))

#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO 口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
//IO 口操作,只对单一的 IO 口!
//确保 n 的值小于 16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
#endif

SysTick定时寄存器 4种

CTRL寄存器

  • 0 使能 1
  • 1 常用0 也就是倒计时为0的时候如果有中断或者特殊的请求 就是1,反之就是0
  • 2 常用0
  • 16 循环判断如果为1代表已经倒计时到0了

LOAD寄存器 (用来重载重新计数的,也就是装弹)

LOAD 是 SysTick 定时器的重装载数值寄存器

VAL寄存器 (用来存储计数的)

VAL 是 SysTick 定时器的当前数值寄存器

CALIB寄存器

CALIB 是 SysTick 定时器的校准数值寄存器
此寄存器在定时实验中不需要使用,可以不用了解。

操作步骤

SysTick 定时器的操作可以分为 4 步:

(1)设置 SysTick 定时器的时钟源。

(2)设置 SysTick 定时器的重装初始值(如果要使用中断的话,就将中断使能打开)。

(3)清零 SysTick 定时器当前计数器的值。

(4)打开 SysTick 定时器

c 复制代码
#include "public.h"
void SysTick_Init(u8 SYSCLK)//SYSCLK:系统时钟频率
{
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //设置系统时钟源为HCLK/8 系统时钟8分频
}

void delay_us(u32 nus)
{   
    u32 u32temp=0;
    SysTick->LOAD=nus*9; //设置计数器的值为nus*9 9M的频率每执行9次为1us
    SysTick->VAL=0; //清空计数器CURRENT
    SysTick->CTRL|=1; //开启计数器 就是第一位为1使能
    do{
        u32temp=SysTick->CTRL; //读取计数器当前值
     //!(u32temp&(1<<16)) 数值一直减减 不为1证明倒计时没结束  u32temp&0x01时钟使能
    }while(!(u32temp&(1<<16))&&(u32temp&0x01)); //死循环等待计数器到达0 
    //时钟失能  也就是第一个比特为0
    SysTick->CTRL&=~1; //关闭计数器
    SysTick->VAL=0; //清空计数器CURRENT
}


void delay_ms(u16 nms)
{
    u32 u32temp=0;
    if(nms>1860) nms=1860; //最大延时1860ms
    SysTick->LOAD=nms*9000; //设置计数器的值为nms*9000
    SysTick->VAL=0; //清空计数器CURRENT
    SysTick->CTRL|=1; //开启计数器
    do{
        u32temp=SysTick->CTRL; //读取计数器当前值
    }while(!(u32temp&(1<<16))&&(u32temp&0x01)); //死循环等待计数器到达0
    SysTick->CTRL&=~1; //关闭计数器
    SysTick->VAL=0; //清空计数器CURRENT
}

迁移过程

初始化

初始化都需要一个初始化系统时钟,否则就会不出现效果

所以这个时候main就需要初始化一个计时器

c 复制代码
int main()
{

	SysTick_Init(72);
	
}

.h的初始化

c 复制代码
//定义引脚
#define LED_PORT					GPIOA				//定义GPIO的组
#define LED_PIN					GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7	    	//定义GPIO的引脚号可以或起来
#define LED_PORT_RCC			RCC_APB2Periph_GPIOA			//定义GPIO的时钟总线

#define RCLK_PORT                GPIOB
#define RCLK_PIN                 GPIO_Pin_5
#define RCLK_PORT_RCC            RCC_APB2Periph_GPIOB

#define SER_PORT                GPIOB
#define SER_PIN                 GPIO_Pin_4
#define SER_PORT_RCC            RCC_APB2Periph_GPIOB

#define SRCLK_PORT                GPIOB
#define SRCLK_PIN                 GPIO_Pin_3
#define SRCLK_PORT_RCC            RCC_APB2Periph_GPIOB

//定义位带
#define RCLK				PBout(5)
#define SER				PBout(4)
#define SRCLK			PBout(3)

.c初始化模板

c 复制代码
void LEDS_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
    // 使能GPIO时钟
    RCC_APB2PeriphClockCmd(LED_PORT_RCC | RCLK_PORT_RCC, ENABLE);
    
    // GPIOB3,4需要重定向
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能复用功能时钟

    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 关闭JTAG接口
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);     // 关闭SWD接口

    GPIO_InitStructure.GPIO_Pin = LED_PIN; //初始化pin
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //初始化模式是推挽
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//频率
    GPIO_Init(LED_PORT, &GPIO_InitStructure); //初始化  组  加结构体指针

    GPIO_InitStructure.GPIO_Pin = RCLK_PIN | SER_PIN | SRCLK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(RCLK_PORT, &GPIO_InitStructure);
}


//寄存器输出
static void _WriteByte(u8 u8data)
{
    // u16 portVal=GPIO_ReadOutputData(LED_PORT);//读取寄存器数据是16位
    // portVal &=0xFF00; //初始化低8位
    // portVal |=u8data;//重载低8位
    // GPIO_Write(LED_PORT,portVal);  //写寄存器数据
    // // 输出数据
    LED_PORT->ODR = (LED_PORT->ODR & 0xFF00) | u8data;  
}
相关推荐
亿道电子Emdoor4 小时前
【ARM】MDK-快捷键添加及修改
arm开发·stm32·单片机
heater4046 小时前
【STM32】stm32启动流程
stm32·单片机·嵌入式硬件
honey ball8 小时前
滤波器的主要参数
人工智能·单片机·嵌入式硬件·学习
浅陌pa9 小时前
RTC:实时时钟
c语言·stm32·单片机·嵌入式硬件
湘の子10 小时前
汇编语言与接口技术--跑马灯
汇编·stm32·单片机·嵌入式硬件·51单片机
佳心饼干-10 小时前
单片机-蜂鸣器实验
单片机·嵌入式硬件
honey ball11 小时前
大功率PCB设计
单片机·嵌入式硬件
黑果果的思考12 小时前
LED背光驱动芯片RT9293应用电路
嵌入式硬件
逝灮12 小时前
【蓝桥杯——物联网设计与开发】Part2:OLED
驱动开发·stm32·单片机·嵌入式硬件·物联网·蓝桥杯·oled
jjddzyh14 小时前
单片机串口控制
单片机·嵌入式硬件