stm8s的c语言编程例程

99ANYc3cd6
预计阅读时长 25 分钟
位置: 首页 C语言 正文

我们将使用 IAR Embedded Workbench for STM8 作为开发环境,这是ST官方推荐的、非常成熟的工具链,也会提及如何使用免费的 ST Visual Develop (STVD) + COSMIC编译器

stm8s的c语言编程例程
(图片来源网络,侵删)

第一部分:开发环境搭建

在写代码之前,我们需要准备好工具。

硬件

  • 一块STM8S Discovery开发板:推荐使用 STM8S-Discovery (型号: STM8S-DISCOVERY),它板上自带ST-Link调试器,非常方便,STM8S105K4T6这款芯片。
  • 一根Micro-USB数据线

软件

  • IAR Embedded Workbench for STM8:
    • 访问 IAR官网 下载免费评估版(有代码大小限制,但对于学习和足够了)。
    • 或者,购买正版许可证。
  • ST Visual Develop (STVD) + COSMIC编译器:
    • 访问 ST官网 下载STVD和免费的COSMIC CXSTM8编译器。
    • 这是完全免费的组合,非常适合初学者。

安装与驱动

  • 安装你选择的IDE(IAR或STVD)。
  • STM8S Discovery板上的ST-Link调试器在首次连接时,需要安装USB驱动,Windows通常会自动安装,如果失败,可以从ST官网下载 "STSW-LINK009" 软件包,里面包含驱动。

第二部分:第一个程序 - LED闪烁 (Blinky)

这是所有嵌入式开发的 "Hello, World!",我们将让开发板上的LED灯一秒闪烁一次。

硬件分析

查看 STM8S-Discovery 的原理图,你会发现板载的LED(标记为LD1)连接在 PD4 引脚上,当PD4输出低电平时,LED点亮;输出高电平时,LED熄灭。

核心概念

  • 时钟配置: STM8S默认使用内部高速时钟,但频率可能较低,为了获得更好的性能,我们通常需要配置时钟,例如使用内部16MHz时钟并分频。
  • GPIO配置: 我们需要将PD4引脚配置为推挽输出模式
  • 延时函数: 为了控制闪烁频率,需要一个简单的延时函数。

C语言例程 (基于IAR EWSTM8)

下面是一个完整的Blinky例程。

stm8s的c语言编程例程
(图片来源网络,侵删)
#include "stm8s.h"
// 简单的软件延时函数
// 注意:这是一个粗略的延时,精确延时需要使用定时器
void Delay(uint32_t count)
{
    for (; count > 0; count--);
}
void main(void)
{
    // 1. 初始化时钟系统
    // 使能内部高速时钟,并设置为16MHz
    CLK_HSICmd(ENABLE); // 使能内部高速时钟
    CLK_SYSCLKDiv(CLK_SYSCLKDiv_1); // 系统时钟不分频,为16MHz
    // 2. 初始化GPIO
    // 使能GPIOD端口时钟
    CLK_PeripheralClockConfig(CLK_Peripheral_GPIO, ENABLE);
    // 配置PD4引脚为推挽输出模式
    // GPIO_Pin_4 对应 0x10
    // GPIO_Mode_Out_PP_5mA 推挽输出,最大5mA驱动能力
    GPIO_Init(GPIOD, GPIO_Pin_4, GPIO_Mode_Out_PP_5mA);
    // 3. 主循环
    while (1)
    {
        // 点亮LED (PD4输出低电平)
        GPIO_WriteLow(GPIOD, GPIO_Pin_4);
        Delay(50000); // 延时
        // 熄灭LED (PD4输出高电平)
        GPIO_WriteHigh(GPIOD, GPIO_Pin_4);
        Delay(50000); // 延时
    }
}

如何编译和下载

  1. 在IAR中创建一个新的 "STM8 C/C++ Project"。
  2. 将上面的代码复制到 main.c 文件中。
  3. 编译项目(F7)。
  4. 连接STM8S Discovery板。
  5. 点击 "Download and Debug" (Ctrl+D)。
  6. 程序下载后,点击 "Go" (F5) 运行,你应该会看到板上的LED开始闪烁。

第三部分:基础外设例程

掌握了Blinky,我们就可以尝试更复杂的外设了。

例程1:按键输入

读取开发板上按键的状态(按键标记为 USER,连接在 PC5 引脚上)。

  • 硬件分析: 按键PC5连接到GND,当按键未按下时,PC5被上拉电阻拉高;当按键按下时,PC5被拉到低电平。
  • 软件配置: 将PC5配置为上拉输入模式
#include "stm8s.h"
void main(void)
{
    // 1. 初始化时钟
    CLK_HSICmd(ENABLE);
    CLK_SYSCLKDiv(CLK_SYSCLKDiv_1);
    // 2. 初始化GPIO
    // 使能GPIOC和GPIOD的时钟
    CLK_PeripheralClockConfig(CLK_Peripheral_GPIO, ENABLE);
    // 配置PC5为上拉输入
    GPIO_Init(GPIOC, GPIO_Pin_5, GPIO_Mode_In_PU_No_IT); // 上拉输入,无中断
    // 配置PD4为推挽输出,用于LED
    GPIO_Init(GPIOD, GPIO_Pin_4, GPIO_Mode_Out_PP_5mA);
    while (1)
    {
        // 读取PC5引脚状态
        if (GPIO_ReadInputPin(GPIOC, GPIO_Pin_5) == RESET)
        {
            // 如果为低电平,说明按键按下
            GPIO_WriteLow(GPIOD, GPIO_Pin_4); // 点亮LED
        }
        else
        {
            // 如果为高电平,说明按键未按下
            GPIO_WriteHigh(GPIOD, GPIO_Pin_4); // 熄灭LED
        }
    }
}

例程2:定时器中断 - 精确延时

软件延时不精确且会阻塞CPU,使用定时器中断是更好的方式,我们将使用 TIM2 来产生一个1ms的定时中断,并利用它来精确控制LED闪烁。

  • 核心概念:
    1. 配置TIM2,使其在1ms后产生中断。
    2. 编写TIM2的中断服务函数。
    3. 在主循环中,通过一个标志位来响应中断,实现非阻塞的延时。
#include "stm8s.h"
volatile uint16_t timer_counter = 0; // volatile关键字,防止编译器优化
// TIM2中断服务函数
// 在STM8标准外设库中,中断函数需要用 @interrupt 关键字声明
INTERRUPT(TIM2_UPD_OVF_IRQHandler, TIM2_UPD_OVF_VECTOR)
{
    // 清除中断标志位,这一步非常重要!
    TIM2_ClearFlag(TIM2_FLAG_Update);
    timer_counter++; // 每次中断,计数器加1
}
void main(void)
{
    // 1. 初始化时钟
    CLK_HSICmd(ENABLE);
    CLK_SYSCLKDiv(CLK_SYSCLKDiv_1);
    // 2. 初始化GPIO
    CLK_PeripheralClockConfig(CLK_Peripheral_GPIO, ENABLE);
    GPIO_Init(GPIOD, GPIO_Pin_4, GPIO_Mode_Out_PP_5mA);
    // 3. 初始化TIM2定时器
    CLK_PeripheralClockConfig(CLK_Peripheral_TIM2, ENABLE); // 使能TIM2时钟
    // 设置预分频器,使定时器时钟为 16MHz / 16 = 1MHz
    TIM2_PrescalerConfig(TIM2_Prescaler_16);
    // 设置自动重装载值,使定时器每 1000 个计数 (1/1MHz * 1000 = 1ms) 中断一次
    TIM2_SetAutoreload(999);
    // 使能更新中断
    TIM2_ITConfig(TIM2_IT_Update, ENABLE);
    // 使能TIM2
    TIM2_Cmd(ENABLE);
    // 4. 使能全局中断
    enableInterrupts();
    // 5. 主循环
    while (1)
    {
        // 每500次中断,即500ms (0.5秒) 切换一次LED状态
        if (timer_counter >= 500)
        {
            timer_counter = 0; // 复位计数器
            // 翻转LED状态
            if (GPIO_ReadOutputData(GPIOD) & GPIO_Pin_4)
            {
                GPIO_WriteLow(GPIOD, GPIO_Pin_4);
            }
            else
            {
                GPIO_WriteHigh(GPIOD, GPIO_Pin_4);
            }
        }
    }
}

例程3:UART串口通信

通过UART向PC发送数据,是调试和通信的重要手段,我们将使用 USART1,其默认引脚为 PA9 (TX)PA10 (RX)

  • 硬件准备: 需要一个USB-TTL转换器(如CH340、FT232)。
    • STM8S-DiscoveryUSART1_TX (PA9) 连接到 USB-TTL 的 RX
    • STM8S-DiscoveryUSART1_RX (PA10) 连接到 USB-TTL 的 TX
    • 共同GND。
  • 软件配置: 配置USART1为波特率9600,8位数据位,1位停止位,无校验位。
#include "stm8s.h"
// 发送一个字符
void UART_SendChar(char c)
{
    // 等待发送数据寄存器为空
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    // 发送数据
    USART_SendData8(USART1, c);
}
// 发送一个字符串
void UART_SendString(char *str)
{
    while (*str)
    {
        UART_SendChar(*str++);
    }
}
void main(void)
{
    uint32_t counter = 0;
    // 1. 初始化时钟
    CLK_HSICmd(ENABLE);
    CLK_SYSCLKDiv(CLK_SYSCLKDiv_1);
    // 2. 初始化GPIO
    // 使能GPIOA和USART1的时钟
    CLK_PeripheralClockConfig(CLK_Peripheral_GPIOA, ENABLE);
    CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);
    // 配置PA9 (TX) 为复用功能推挽输出
    GPIO_Init(GPIOA, GPIO_Pin_9, GPIO_Mode_Out_PP_High_Fast);
    // 配置PA10 (RX) 为浮空输入
    GPIO_Init(GPIOA, GPIO_Pin_10, GPIO_Mode_In_FL_No_IT);
    // 3. 初始化USART1
    USART_Init(USART1, 9600, USART_WordLength_8b, USART_StopBits_1, USART_Parity_No, USART_Mode_TxRx);
    USART_Cmd(USART1, ENABLE);
    // 4. 主循环
    while (1)
    {
        UART_SendString("Hello from STM8S!\r\n");
        UART_SendString("Counter: ");
        // 将数字转换为字符串并发送 (这里简化处理,实际应用中应使用sprintf或itoa)
        char buf[16];
        itoa(counter, buf, 10); // itoa不是标准C,但很多编译器支持
        UART_SendString(buf);
        UART_SendString("\r\n");
        counter++;
        Delay(500000); // 粗略延时1秒
    }
}

第四部分:重要资源与学习建议

  1. 数据手册: 每个芯片最重要的文档,必须仔细阅读,特别是关于引脚定义、电气特性、寄存器描述和时序图的部分。
  2. 参考手册: 描述了STM8S系列所有外设的功能和寄存器,当你想配置一个定时器、SPI或I2C时,这里就是你的字典。
  3. STM8S标准外设库: ST官方提供的C语言库,它将复杂的寄存器操作封装成了简单的函数(如 GPIO_Init, TIM2_PrescalerConfig)。强烈建议初学者使用,可以大大提高开发效率,避免直接操作寄存器时出错。
  4. 例程: ST官方提供了大量针对不同外设的例程,可以在ST官网上下载,这些例程是学习如何使用库函数的绝佳材料。

学习建议:

  • 从GPIO开始: 熟悉如何配置和使用输入输出。
  • 掌握定时器: 定时器是单片机的核心,学会配置和使用定时器中断是进阶的关键。
  • 学习UART: 这是与外界交互最简单的方式,是调试利器。
  • 逐步深入: 在掌握了GPIO、定时器、UART后,再尝试学习更复杂的外设,如 SPI (用于Flash、OLED屏)、I2C (用于传感器、EEPROM)、ADC (用于模拟信号采集)

希望这份详细的例程能帮助你顺利入门STM8S的C语言编程!

-- 展开阅读全文 --
头像
C语言图书管理系统实验报告如何实现核心功能?
« 上一篇 03-04
如何给dede添加留言功能?
下一篇 » 03-04

相关文章

取消
微信二维码
支付宝二维码

目录[+]