STM32学习之旅③ 从点灯到代码移植


目录:

一、认识其本质


  • 为什么很多单片机教程第一课都是用单片机点一个灯?就和软件编程的第一个程序都是Hello World!一样,很多人也说不上为什么,可能是历史原因,有人这样做了,别人看到了也去模仿然后也成功了。但是在我看来,成功点亮一个灯不仅仅意味着点亮了一个灯,其实已经离学会使用不远了,这个灯的点亮其实背后对应着开发环境的配置、程序文件的配置以及源文件的编译、链接到可执行文件的一步步生成完成了。但是学会使用仅仅指会操作STM32对应的的外设,更多的还是取决于嵌入式软件设计的水平。

二、所需材料



三、添加文件


  • main.c文件中添加如下代码
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "nokia5110.h"
int main()
{
    RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC, ENABLE); //开 GPIOA 时钟
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;             //选择要初始化的引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //GPIO的工作状态为推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;      // GPIO的速率最高输出速率 50Hz
    GPIO_Init(GPIOC, &GPIO_InitStructure);                 //初始化 GPIOA
    while(1)
    {         
        GPIO_SetBits(GPIOC, GPIO_Pin_13);  //将 GPIO的A端口第二个管脚置为高电平,即PA.1=1;
        delay_us(0x8ffff);
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);//将 GPIO的 A端口第二个管脚置为低电平,即PA.1=0;
        delay_us(0x8ffff);
    }
}

四、程序下载


(一)用ST-Link下载


  • 插上ST-Link,装上对应的驱动,然后在IAR中进行对应的设置,Option->Debugger->Setup->Driver->ST-Link->Download->勾选Use flash loader(s)和Override default .board file

  • 在ST-Link中勾选SWD,然后OK
    这里写图片描述
    这里写图片描述
    这里写图片描述

  • Make,编译无误后点Download and Debugger->go
    可以看到灯亮了

  • 问题分析:

    1. Make编译不过,检查头文件是否包含,主要以编译器的输出信息为准
    2. 无法下载,检查驱动是否安装,检查Option中设置是否正确

(二)用串口下载


  • 在Option中设置使编译之后生成.hex文件
    这里写图片描述

  • 如图,点OK然后Make,就可以在对应文件夹中找到对应的.hex文件
    这里写图片描述

  • 打开Flash Loader Dome,选择对应的文件,下载就行了



五、文件移植


  • 能够点亮一个灯后,说明编译环境没问题,对GPIO的设置也没问题,可以开始代码的移植了,我用nokia5110作为显示器,用GPIO模拟spi时序来写lcd显示器,自己写了个printf函数,主要通过简单的c语言逻辑实现。比较可惜的是之前写的缓冲区是基于msp430f5529的硬件的,移植起来比较麻烦,所以用了模拟spi,不过stm32的72MHz主频果然不是盖的,用GPIO 模拟spi经看不出任何延迟,十块钱不到的东西这么好用,怪不得那么多人玩stm32。废话不多说,开始移植

  • 将gitub上clone的.c和.h文件添加到工程中
    这里写图片描述
    这里写图片描述

  • 然后将.c文件在IAR中添加到工程中,Add->Add File…->选择.c文件

这里写图片描述

  • 在main.c文件中添加如下代码
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "nokia5110.h"
int main()
{
    LCD_Init();
    unsigned long d = 33;
    while(1)
    {   
        d++;
        printf("\n\n Hello World!\n\n     %d\n",&d);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);//将 GPIO的A端口第二个管脚置为高电平,即PA.1=1;
        delay_us(0x8ffff);
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);//将 GPIO的 A端口第二个管脚置为低电平,即PA.1=0;
        delay_us(0x8ffff);
    }
}
  • 这是自己写的printf的算法
void printf (unsigned char *String, volatile unsigned long *Adress)
{
    static int DISPBUFF[84];
    static unsigned long Num;
    Num = *Adress;
    memset (DISPBUFF, 0, sizeof(DISPBUFF));
    unsigned char X_Disp, Y_Disp;
    X_Disp = 0;
    Y_Disp = 0;
    unsigned char i;
    static unsigned char X_Set;
    X_Set = 0;
    while (*String)
    {
        if (*String == '%')
        {
            String++;
            switch(*String)
            {
                case 'd':
                {
                    for (i = 0; i < ByteLengh; i++)
                    {
                        DISPBUFF[X_Set+ByteLengh-i-1] = Num%10 + 48;
                        Num = Num/10;
                    }
                    for (i = 0; i < ByteLengh - 1; i++)
                    {
                        if (DISPBUFF[X_Set+i] == 48)
                            DISPBUFF[X_Set+i] = 32;
                        else
                            break;
                    }
                    X_Set += ByteLengh;
                    String++;
                    break;
                }
                /*
                case 'f':
                {
                    float valflt = va_arg(ap,double);
                    printfloat(valflt);
                    String++;
                    break;
                } */
                default:
                {
                    String--;
                    DISPBUFF[X_Set] = '%';
                    String++;
                }
            }
        }
        else if(*String == '\n')
        {
            DISPBUFF[X_Set] = '\n';
            X_Set++;
            String++;
        }
        else
        {
            DISPBUFF[X_Set] = *String;
            X_Set++;
            String++;
        }
    }
    LCD_Set_XY (X_Disp, Y_Disp);

    unsigned char Line_Num;
    Line_Num = 0;
    for (i = 0; i < X_Set; i++)
    {
        if (DISPBUFF[i] == '\n')
        {
            Line_Num++;
            LCD_Set_XY(0, Y_Disp+Line_Num);
        }
        else
            LCD_Write_Char (DISPBUFF[i]);
    }
    //UCA0IFG |=UCTXIFG;
}
  • Make->下载,把线接上,可以看到nokia5110上的显示
    这里写图片描述


  • 感觉方向不对,再来一个
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "nokia5110.h"
int main()
{
    LCD_Init();
    unsigned long d = 33;
    while(1)
    {   
        d++;
        printf("\n\n  Good Luck!\n\n",&d);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);//将 GPIO的A端口第二个管脚置为高电平,即PA.1=1;
        delay_us(0x8ffff);
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);//将 GPIO的 A端口第二个管脚置为低电平,即PA.1=0;
        delay_us(0x8ffff);
    }
}

这里写图片描述

  • 如lcd所示,

    Good Luck!

回到顶部

猜你喜欢

转载自blog.csdn.net/qq_39432978/article/details/81711087