你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于一块测线板,让你从STM8S从入门到提高  

[复制链接]
w453509596 发布时间:2015-1-8 21:14
本帖最后由 w453509596 于 2015-1-9 13:01 编辑

    我刚刚使用STM8S几个月,从刚开始到现在会使用,在这过程中也走了很多的弯路,浪费了许多时间。我看到也有一些刚接触STM8的同学和我刚开始一样,对于入门STM8无从下手。我在这里把我入门的过程给分享出来,希望能对想入门STM8S的同学有所帮助。根据我个人的学习经历,感觉初学者最需要的是从一个实际的项目入手,让初学者在不熟悉其全部理论的情况下也可以把东西做出来,然后再回过头来去理解其中的全部原理。我的STM8入门是从一个测线板开始的,我把我的学习过程和其中碰到的问题全部写了来。
   1 准备工作: 一块STM8学习板,编程软件,数据手册,参考手册, 一颗坚不可崔的决心。
   想做成一个东西,兴趣、压力、动力,这几点非常重要,我希望朋友们在学习STM8之前能给自己找一个学习的理由,绝对会事办功倍,我当初给自己设了一个理由,我学会了STM8S,就能够涨工资,然后就可以找到个漂亮的女朋友。学习STM8有着他天然的优势,首先这芯片价格便宜(香蕉超市最便宜卖2块2,它最便宜的只要1块5);其次,学习它只需要用到我们最喜爱的语言(chinese Simple);再次它的官方资料非常多,官方库的程序很直观,不像飞思卡尔什么的,各种秀操作。最后还有我们这个强大的社区  (https://www.stmcu.org.cn/)。我当时的资料全部都在这个社区找的。


收藏 5 评论44 发布时间:2015-1-8 21:14

举报

44个回答
w453509596 回答时间:2015-1-8 21:14:41
本帖最后由 w453509596 于 2015-1-8 21:09 编辑

     我的板子是我自己做的,上面有一个四位共阴数码管,8个LED和8个按键,一个蜂鸣器,一组测12根排线通断的接线口,一组用RS485芯片引出来的串口。我的板子的原理图和PCB我会在附件中提供。想要学习好STM8S单片机,大家也最好能有一块开发板,淘宝上卖的很便宜,少吃点香蕉就可以买到了,卖家还提供有很多的例程,个人建议大家买个简单的板子,有条件的话,建议自己做一个。
    目前STM8S的编程软件有 IAR FOR STM8  和官方的STVD ,个人强列推荐IAR FOR STM8,STVD比较难用,我两者都用过,现在一直在用 IAR FOR STM8 1.3(这个软件大家自己网上搜了,比超市里的香蕉还要多)
   我的板子用的芯片是STM8S207RB ,对应的数据手册和参考手册在这里直接下载。(https://www.stmcu.org.cn/document/list/index/category-17 ),第一个和第二个就是(RM0016 参考手册 和 DS5839 数据手册)。数据手册是介绍该芯片里面有哪些资源、片上外设供大家使用,以及它的电气参数(相当于超市里面挂在香蕉前面的牌子)。而参考手册刚是介绍如使用编程这款芯片了(其实这款芯片毕竟是8位单片机,入门也相对比较简单,祝大家早日能像吃香蕉一样简单的用它)。我的原理图和PCB是用 altium designer 9.3画的。
   还有个官方的STM8S /标准外围库:  https://www.stmcu.org.cn/document/li ... ew/category-504?p=2    (倒数第二个STSW-STM8069)
   如果你用到的芯片也是STM8S207RB的话,直接用我的附件的中的 工程模板就可以了。代码库中有帮助文挡和官方例程。
   最后还有个福利,标准外围库,中文函数生成器,在附件中(STM8S真是好,这也能有! ! ! 被天上的馅饼砸中了,满满的都是幸福! ! !)
测线板PCB.png
测线板原理图.png

测线板原理图.pdf

下载

507.07 KB, 下载次数: 228

原理图

测线板PCB.rar

下载

519.81 KB, 下载次数: 174

PCB

STM8S工程模板.rar

下载

348.53 KB, 下载次数: 250

工程模板

stm8slib.rar

下载

80.76 KB, 下载次数: 186

w453509596 回答时间:2015-1-8 21:21:01
告诉大家个小秘密,想要加快STM8的学习步伐,可以观看下STM8的视频教程,别人开发板的教程。
zhous 回答时间:2015-1-8 21:35:03
测线板是干什么用的?
jcrorxp 回答时间:2015-1-8 21:48:20
zhous 发表于 2015-1-8 21:35
测线板是干什么用的?

同问
是不是类似网线那种, 通断显示

111111.jpg 22222.png

w453509596 回答时间:2015-1-8 21:56:18
本帖最后由 w453509596 于 2015-1-8 22:22 编辑

首先编程软件的安装,开发环境的搭建,以及想自己建立工程模板的同学们,请参考附件。我在这里介绍如何驱动我的板子上面的LED。
  从原理图上可以看出,我的8颗LED连接PG0~PG7上面,公共端连接在ULN2003A上,由PE0端口驱动。如果我想要第 1 个小灯点亮,只要 PG = 0x01 , PE0 = 1 即可。
  如查想做个LED的闪烁效果,大家可以在MAIN文件中加上如下一段简单的程序

void delay(unsigned int t)   
{
  unsigned char i;
  while(t--)
  {
    for(i=0;i<250;i++);
  }
}

void main(void)
{
   GPIO_DeInit(GPIOG);  //复位G端口寄存器
   GPIO_DeInit(GPIOE);  //复位E端口寄存器
   
   GPIO_Init(GPIOG,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_LOW_SLOW); //初始化GPIOG为推挽 低速 输出
                                                                                                                //初始电平为低电平
   GPIO_Init(GPIOE,GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_SLOW);   //初始化GPIOE0为推挽 低速 输出
                                                                                                               //初始电平为低电平
   
   GPIO_WriteHigh(GPIOE, GPIO_PIN_0);   //打开LED的公共端  即 PE0 = 1
  /* Infinite loop */
  while (1)
  {
    GPIO_WriteHigh(GPIOG, GPIO_PIN_0);   //点亮第1个LED   即PG0 = 1
    delay(1000);                                          //延时一小段时间
    GPIO_WriteLow(GPIOG, GPIO_PIN_0);   //关闭每1个LED   即PG0 = 0
    delay(1000);                                          //延时一小段时间
  }
}

在这段程序中,单片机使用的是上电复位后默认的初始化(内部16M的参考时钟8分频,即2MHz作为系统主频)。

GPIO_Init(GPIOG,GPIO_PIN_ALL,GPIO_MODE_OUT_PP_LOW_SLOW);函数的原型如下
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode)
它的功能是初始化一个端口的指定引脚为某种状态

这个函数它有三个参数,
第一个 GPIO_TypeDef*   GPIOx    ( 选择端口)
其中这个 GPIOx   可以替换成 GPIOA 、 GPIOB、 GIPOC、GPIOD、GPIOE、GPIOF

第二个参数是  GPIO_Pin_TypeDef   GPIO_Pin      (选择引脚)  
其中这个 GPIO_Pin 可以替换成下面这些
  GPIO_PIN_0    = ((uint8_t)0x01),  /*!< Pin 0 selected */
  GPIO_PIN_1    = ((uint8_t)0x02),  /*!< Pin 1 selected */
  GPIO_PIN_2    = ((uint8_t)0x04),  /*!< Pin 2 selected */
  GPIO_PIN_3    = ((uint8_t)0x08),   /*!< Pin 3 selected */
  GPIO_PIN_4    = ((uint8_t)0x10),  /*!< Pin 4 selected */
  GPIO_PIN_5    = ((uint8_t)0x20),  /*!< Pin 5 selected */
  GPIO_PIN_6    = ((uint8_t)0x40),  /*!< Pin 6 selected */
  GPIO_PIN_7    = ((uint8_t)0x80),  /*!< Pin 7 selected */
  GPIO_PIN_LNIB = ((uint8_t)0x0F),  /*!< Low nibble pins selected */
  GPIO_PIN_HNIB = ((uint8_t)0xF0),  /*!< High nibble pins selected */
  GPIO_PIN_ALL  = ((uint8_t)0xFF)   /*!< All pins selected */

第三个参数是  GPIO_Mode_TypeDef   GPIO_Mode  (选择模式)
其中这个 GPIO_Mode 可以替换成下面这些
GPIO_MODE_IN_FL_NO_IT      = (uint8_t)0x00,  /*!< Input floating, no external interrupt */
  GPIO_MODE_IN_PU_NO_IT      = (uint8_t)0x40,  /*!< Input pull-up, no external interrupt */
  GPIO_MODE_IN_FL_IT         = (uint8_t)0x20,  /*!< Input floating, external interrupt */
  GPIO_MODE_IN_PU_IT         = (uint8_t)0x60,  /*!< Input pull-up, external interrupt */
  GPIO_MODE_OUT_OD_LOW_FAST  = (uint8_t)0xA0,  /*!< Output open-drain, low level, 10MHz */
  GPIO_MODE_OUT_PP_LOW_FAST  = (uint8_t)0xE0,  /*!< Output push-pull, low level, 10MHz */
  GPIO_MODE_OUT_OD_LOW_SLOW  = (uint8_t)0x80,  /*!< Output open-drain, low level, 2MHz */
  GPIO_MODE_OUT_PP_LOW_SLOW  = (uint8_t)0xC0,  /*!< Output push-pull, low level, 2MHz */
  GPIO_MODE_OUT_OD_HIZ_FAST  = (uint8_t)0xB0,  /*!< Output open-drain, high-impedance level,10MHz */
  GPIO_MODE_OUT_PP_HIGH_FAST = (uint8_t)0xF0,  /*!< Output push-pull, high level, 10MHz */
  GPIO_MODE_OUT_OD_HIZ_SLOW  = (uint8_t)0x90,  /*!< Output open-drain, high-impedance level, 2MHz */
  GPIO_MODE_OUT_PP_HIGH_SLOW = (uint8_t)0xD0   /*!< Output push-pull, high level, 2MHz


GPIO_TypeDef 是一个结构体类型 ,它的定义如下: (这个对于初学单片机的同学可以不用关心)
typedef struct GPIO_struct
{
  __IO uint8_t ODR; // 数据输出寄存器
  __IO uint8_t IDR; //数据输入寄存器
  __IO uint8_t DDR; //端口方向寄存器  
  __IO uint8_t CR1; //控制寄存器1
  __IO uint8_t CR2; //控制寄存器2
}
GPIO_TypeDef;

#define GPIOA ((GPIO_TypeDef *) GPIOA_BaseAddress)   //这里是为从 GPIOA_BaseAddress 到  GPIOA_BaseAddress + 5 这段地址                                                                                                 //取个名字叫GPIOA  ,STM8所的寄存器都是差不多这样定义的
#define GPIOB ((GPIO_TypeDef *) GPIOB_BaseAddress)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BaseAddress)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BaseAddress)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)











LED.rar

下载

351.84 KB, 下载次数: 70

示例程序

2-开发环境搭建.pdf

下载

614.44 KB, 下载次数: 110

搭建开发环境

3-如何使用库来创建自己的工程.pdf

下载

809.16 KB, 下载次数: 127

建工程模板

5-LED(GPIO).pdf

下载

500.56 KB, 下载次数: 75

风驰的教程

w453509596 回答时间:2015-1-8 21:57:07
jcrorxp 发表于 2015-1-8 21:48
同问
是不是类似网线那种, 通断显示

是这样的一个功能。
w453509596 回答时间:2015-1-8 21:59:08

STM8s定时器的使用程序

本帖最后由 w453509596 于 2015-1-9 09:33 编辑

  STM8S包含有三种定时器,高级定时器,通用定时器和基本定时器,这三种定时器在功能上是包含关系的。在这里做一段最简单的1ms的定时功能。
  static void MCU_TIM2_Init(void)  //定时器2 1ms中断初始化
{
  TIM2_DeInit();                                                                 //复位所有寄存器值,这一步呢可选,为了产品稳定性,最好还是选上
  TIM2_TimeBaseInit(TIM2_PRESCALER_1, 0x07d0);          //2M 内部时钟,一分频 2000
  TIM2_UpdateDisableConfig(DISABLE);                             //允许更新    即是在每一次定时器溢出之后,会自动更新计数器
  TIM2_UpdateRequestConfig(TIM2_UPDATESOURCE_REGULAR);  //只允许规则请求更新,即是只允许定时器溢出更新
  TIM2_ITConfig(TIM2_IT_UPDATE, ENABLE);                //打开定时器溢出中断
  TIM2_Cmd(ENABLE);                                                   //启动定时器
}

通过上面的一段程序即实现1ms 的定时功能 :我的这个示例是在默认的系统时钟,2M / 1000 = 2000 ,所以模寄存器的值0x07d0。大家是别的主频的
话,根据想要定时的周期,对应的调相关系数即可。有库函数用起来真的很简单。我再上传一个风驰大哥的教程。

有了定时器的中断,必有中段函数,库模板已在库函数 stm8s_it.c中写好了
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)  //定时器2溢出中断
{
   /*  用户函数*/
   TIM2_ClearITPendingBit(TIM2_IT_UPDATE);          //清除定时器2溢出中断
}


10-TIM1(定时).pdf

下载

428.3 KB, 下载次数: 73

TM1定时

w453509596 回答时间:2015-1-8 21:59:23

数码管驱动

本帖最后由 w453509596 于 2015-1-9 09:58 编辑

数码管驱动分为动态驱动和静态驱动。这里只讲我的动态驱动的设计方案供大家参考
我以前上学时老师教的动态驱动是这样的。
void main(void)
{
    while(1)
    {
        display_ONE();     //第一位数码管点亮
        delay_MS(10);     //延时个10ms
        display_TWO();     //第一位数码管点亮
        delay_MS(10);
        display_THR ();     //第一位数码管点亮
        delay_MS(10);
    }
}
  这样的写法只适用学习如何动态显示数码管,他有两个不足的地方,一个是延时函数浪费了很多处时器时间,另一个是如果这个循环中再加上别的任务,随着工程量的加大,数码管就会越来越暗,有时候甚至不亮了。那么怎么办呢,那就得要基于动态显示的原理进行改进了。在上一段中,介绍了定时器,我分享下我的方法。我是把 这段程序放在中断中。
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{
  switch(Dispay_Index)                    
  {
      case 0: LED4_Disable();Dispay_Index = 1;LED_Data=LED_Buff[4];LED0_Enable();break;       //LED指示灯
      case 1: LED0_Disable();Dispay_Index = 2;LED_Data=LED_Buff[0];LED1_Enable();break;       //第一位数码
      case 2: LED1_Disable();Dispay_Index = 3;LED_Data=LED_Buff[1];LED2_Enable();break;       //第二位数码
      case 3: LED2_Disable();Dispay_Index = 4;LED_Data=LED_Buff[2];LED3_Enable();break;       //第三位数码
      case 4: LED3_Disable();Dispay_Index = 5;LED_Data=LED_Buff[3];LED4_Enable();break;       //第四位数码
      default  : LED4_Disable();Dispay_Index = 0;KEY_Scan();break;    //扫描按键
  }
}
我的这段程序是这样的一个功能,每次进中断,更换显示一位数码管。在中断中可使数码管的显示与工程的主任务独立起来。不管其它地方如何变化,
数码管的显示总会是稳定的。Dispay_Index 它是一个全局变量。如果临时变量的话,在退出中断时它的值就消失了。最后default建议大家一定要使
用,因为它使得这个显示程序具有程序跑飞时的自我修正能力。由于我的LED和数码管是共用段码口的。所以我把LED就当作一位数码管来看待了。
我的按键也是共用端口的,所以我也是把它当作一位数码管来看待的,只不过数码管是输出,它是输入而已。下一段我和大家分享一下我的按键驱动
方法
  
  



w453509596 回答时间:2015-1-8 21:59:40

STM8S按键驱动

本帖最后由 w453509596 于 2015-1-9 11:30 编辑

     按键分为独立按键和矩阵按键,矩阵按要比独立按键省I/O口,但是驱动程序要复杂。这两者各种有利有弊,那么有没有两者兼得的方法呢。如果的你的工程中有段式LED的话,恭喜你中奖了,看看我的方法吧。
    从我的测线板的原理图中可以看出,我在不增加I/O的情况下,让我的测线板多上了8个独立按键。那么如何驱动这8个独立按键呢。以前学
的都是,先判断到有按键按下,再等10ms,如果按键还是按下的,则置下按键按下标志。那么问题来了,10ms的延时(不符合节约的原则),还有
如果我的按是长按的怎么处理呢。我分享下我的方法。我也是在中断中处理的。
    我会为什么时候执行显示,什么时候处理按键检测 排个次序。有点类似操作系统中的分时复用。现在把执行按检测的部分独立起来看。
    每次执行按键检测的时候,我会先判断8个按键的状态,看看有没有被按下,如果没有,则不用理会。如果有,则记下一标记,下一次时中断,还
有按下,那好了,程序就认定有按键按下了,接下来的连续几次进中断,还是有按下,则认定它为长按了。我附上我的程序。


KEYStatusDef KEYStatus;     //按键的状态 分为三种: 没有按下;   已经按下了,等待下一个中断确认; 等待按键松开,或确认为长按
KEYValueDef  KEY_Value;
FunctionStatus KEY_Flag;
static Uint8  KEY_Temp1;
static Uint8  KEY_Temp2;

static void KEY_PortScan(void)   // 从没有按键按下到按键的确认
{
  KEY_Temp1 = KEY_Data;
  if(KEY_Temp1 != 0xff)
  {   
    KEYStatus = KEYStatus_Ok;
  }
}

static void KEY_PortOk(void)      //从确认按键下到等待按键的松开
{
  KEY_Temp2 = KEY_Data;
  if((KEY_Temp2 == KEY_Temp1)&&(KEY_Temp2 != 0xff))   //再次判断按键,如果值和上次相同,则认定有按键按下
  {
    KEY_Value = (KEYValueDef)KEY_Temp2;         //保存按键值
    KEYStatus = KEYStatus_Pro;
    KEY_Flag = L_TRUE;                                      //置按键按下标志位
  }else KEYStatus = KEYStatus_Scan;   
}

static void KEY_PortPro(void)      //判断按键的松开,去检测下一个按键的按下
{
  KEY_Temp1 = KEY_Data;
  if(KEY_Temp1 == 0xff) KEYStatus = KEYStatus_Scan;
  else /*判断按键 长按*/
}

static void KEY_Scan(void)
{
  KEY_Input();                 // 置I/O为输入端口,用来检测按键输入功能
//在主频比较大时,内核的处理速度大于I/O的处理速度,因为I/O最大输出速度只有10M,输入更低。STM8S最高主频有24M,这里加空操作,数量按实//际测试而定,我为工程的稳定性,很保留的加了10个nop();,5个也可以了。
#if UserSystemClock > 6      
  nop(),nop(),nop(),nop(),nop(),nop(),nop(),nop(),nop(),nop();  
#endif
  if(KEYStatus == KEYStatus_Pro) KEY_PortPro();        //有按键按下,等待按键松开或按键长按认定
  else if(KEYStatus == KEYStatus_Ok) KEY_PortOk();   //确认按键按下
  else KEY_PortScan();                                                 //扫描有没有按键按下,  这一个放在最后,用 else,也是为了让程序具有自动修复能力
  KEY_Output();              //置I/O为输出端口,用于显示功能
}

void KEY_Varible_Init(void)     //初始化按键相关变量的初始值.
{
  KEYStatus = KEYStatus_Scan;
  KEY_Value = KEYVal_NO;
  KEY_Temp1 = 0xff;
  KEY_Temp2 = 0xff;
  KEY_Flag = L_FASE;
}


上面的介绍只是代码部分,硬件部分有个地方大家要注意,就是那个按键公共端上面接了一个电阻R10。它取值很重要,为了防止在按键按下时,数码管对应的段不亮。综合下面的两点,我的板子上R10实际取的是2K;

1  参考STM8SR207RB数据手册,STM8认定0.3VDD为低电平,保守一点,最好不要超过0.15倍VDD。而按的上接电阻是33K,其实有点大了,
    我实际焊板测试后,选取的是22K,因为这直接影响了前面判断按键状态的准确性,还有一点大家不要忽视了,芯片内部还有个上接电阻,
   根据数据手册 上接电阻为30~80K.
2 数码管点亮它有一个压降(大家不要认数码管也是0.7V),大多数码管是2~3V的样了。所以数码管与单片机连接处加一个限流电阻,这个电
   阻是多少?
      a,数码管点亮2ma足够了。(5 - 3)/ 2 = 1K  ,尽可能的减小这个电流,单片机驱动能力是有限的
      b , I/O输出的5V分在限流电阻和R10上,保证R10的电压大于3V。



端口电气特性

端口电气特性
12345下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版