打印
[STM8]

一天天学用STM8

[复制链接]
楼主: dadodo
手机看帖
扫描二维码
随时随地手机跟帖
21
yybj| | 2010-8-8 14:41 | 只看该作者 回帖奖励 |倒序浏览
楼主是在分享成功的喜悦,值得推荐

使用特权

评论回复
22
txcy| | 2010-8-8 16:57 | 只看该作者
LZ继续努力啊

使用特权

评论回复
23
无冕之王| | 2010-8-12 09:54 | 只看该作者
楼主学了多少天了

使用特权

评论回复
24
yybj| | 2010-8-12 10:34 | 只看该作者
楼主不能只学一款芯片

使用特权

评论回复
25
dfsa| | 2010-8-12 15:27 | 只看该作者
楼主一天天都在进步

使用特权

评论回复
26
yewuyi| | 2010-8-12 15:46 | 只看该作者
又多一个用户

使用特权

评论回复
27
jgphu| | 2010-8-12 19:22 | 只看该作者
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

使用特权

评论回复
28
dong2007| | 2010-8-12 22:12 | 只看该作者
楼主玩熟了,估计没兴趣了!

使用特权

评论回复
29
Z赤心木QW| | 2010-8-12 22:53 | 只看该作者
我来围观学习的

使用特权

评论回复
30
pkat| | 2010-8-13 14:31 | 只看该作者
楼主可以考虑再写一个一天天学用STM32:lol

使用特权

评论回复
31
秋天落叶| | 2010-8-13 14:54 | 只看该作者
学习的心得写出来让大家共享,挺好的

使用特权

评论回复
32
sunny_ugv| | 2010-8-13 15:49 | 只看该作者
好东西,MARK

使用特权

评论回复
33
sinadz| | 2010-8-14 09:40 | 只看该作者
我也想一天天学STM8:lol,然后写个心得啥的

使用特权

评论回复
34
xsgy123| | 2010-8-14 10:02 | 只看该作者
不知楼主一共学了多少天了

使用特权

评论回复
35
经典cai| | 2010-8-16 17:03 | 只看该作者
天天跟进

使用特权

评论回复
36
yybj| | 2010-8-17 09:06 | 只看该作者
这贴这么火,楼主是不是考虑再多写点呢

使用特权

评论回复
37
pkat| | 2010-8-17 09:38 | 只看该作者
楼主应该是学到第七天了,如果我没记错的话:lol

使用特权

评论回复
38
dadodo|  楼主 | 2010-8-17 12:44 | 只看该作者
这贴这么火,楼主是不是考虑再多写点呢
yybj 发表于 2010-8-17 09:06

那我再补一点吧,呵呵

  STM8的UART功能强大,除了常规的串口异步通讯外,还拥有LIN主模式、红外编解码器、智能卡模拟等功能。新手还是从基本的串口通讯入手,那些高级功能等熟练以后再慢慢研究吧。

#include <iostm8s207sb.h>

void CLK_init(void)
{
  CLK_CKDIVR = 0x08;         // 16M内部RC经2分频后系统时钟为8M
}
void UART3_init(void)
{
  UART3_BRR2 = 0x01;         // 设置波特率9600
  UART3_BRR1 = 0x34;         // 8M/9600 = 0x341
  UART3_CR2 = 0x2C;          // 允许接收中断,允许接收,允许发送
}
#pragma vector=UART3_R_RXNE_vector
__interrupt void UART3_RX_RXNE(void)
{
  unsigned char c;
  c = UART3_DR;          // 接收到数据了
  while(!UART3_SR_TXE);
  c++;                         // 把接收到的数据加1
  UART3_DR = c;         // 再发回去,为什么这么做?在电脑上串口调试软件里发1就收到2,发A就收到B,看运行结果比较方便
}
void init_devices(void)
{
  asm("sim");  // 关全局中断
  CLK_init();
  UART3_init(); // 开发板上的串口接的是UART3,刚开始想当然的认为UART1,浪费我半个小时
  asm("rim");  // 开全局中断
}
void main( void )
{
  init_devices();
// 主循环里没有程序需要执行
  while(1);
}

使用特权

评论回复
39
dadodo|  楼主 | 2010-8-17 12:48 | 只看该作者
EXTI外部中断控制寄存器

  这块三合一的开发板上有且只有一个按键,没办法,就拿这唯一的按键来用吧。吸取前面UART3的教训,先看开发板的原理图吧。这个按键被接到了STM8S207SB的PD7上,已做了上拉处理。为了简单明了,还是点LED1吧。按一下LED1亮,再按一下LED1灭。好了,写程序吧。

#include <iostm8s207sb.h>

#define LED1_FLASH  PD_ODR_ODR3 =  !PD_ODR_ODR3  // 开发板上的LED1接在PD3上

void GPIO_init(void)
{
  PD_DDR = 0x08;             // 配置PD端口的方向寄存器PD3输出
  PD_CR1 = 0x08;             // 设置PD3为推挽输出
  PD_CR2 = 0x80;             // 使能PD7外部中断
}

void EXTI_init(void)
{
  EXTI_CR1 = 0x80;           // PD口下降沿触发中断
}

#pragma vector=0x02      // 这里很关键!看下面说明。
__interrupt void EXTI_PD7_TLI(void)
{
  LED1_FLASH;
}
void init_devices(void)
{
  asm("sim");  // 关全局中断
  GPIO_init();
  EXTI_init();
  asm("rim");  // 开全局中断
}

void main( void )
{
  init_devices();

// 主循环里没有程序需要执行
  while(1);
}

  这里着重要说明的一点是PD7的外部中断程序。看了一下芯片手册,PD口外部中断EXTI3的中断向量号是6,想当然,又是想当然,按IAR的规矩中断向量要加2,就这样写#pragma vector=0x08,结果就是按下按键,程序没响应了,一直在中断里不出来。接下来只能另想办法,仔细翻了资料后发现,PD7和PD其他端口不一样,PD7后面拖了个小尾巴TLI,再看手册上的TLI描述,乖乖,TLI拥有芯片最高级别中断,享有独立专用的中断向量号0,这下就好办了,按IAR的规矩,向量号加2,程序改成#pragma vector=0x02,重新来一遍编译、下载、运行,按键终于听话了。

使用特权

评论回复
40
dadodo|  楼主 | 2010-8-17 12:55 | 只看该作者
一天天学用IAR+STM8——ADC模数转换器

  STM8片上集成了10位逐次比较型模数转换器,在开发板上有个电位器接到了AIN3,但没有可以显示数据的LED数码管或LCD液晶显示屏,怎么办呢?通过前面的学习,这个问题不难解决,可以把AD采集数据通过UART发送到电脑上显示。

#include <iostm8s207sb.h>

void CLK_init(void)
{
  CLK_CKDIVR = 0x08;         // 16M内部RC经2分频后系统时钟为8M
}

void GPIO_init(void)
{
  PD_DDR = 0x08;             // 配置PD端口的方向寄存器PD3输出
  PD_CR1 = 0x08;             // 设置PD3为推挽输出
  PD_CR2 = 0x80;             // 使能PD7外部中断
}

void EXTI_init(void)
{
  EXTI_CR1 = 0x80;           // PD口下降沿触发中断
}

#pragma vector=0x02
__interrupt void EXTI_PD7_TLI(void)
{
  unsigned int value;
  ADC_CSR &= ~0x80;       // 清除EOC转换结束标志
  ADC_CR1 |= 0x01;           // 开始单次转换
  while(!(ADC_CSR&0x80));    // 等待单次转换完成
  value = ((int)ADC_DRH<<2); // 先读高8位,默认设置数据左对齐
  value |= ADC_DRL;                 // 再读低8位
  while(!UART3_SR_TXE);
  UART3_DR = value;               // 通过UART3发送AD采样结果
  while(!UART3_SR_TXE);
  UART3_DR = value>>8;
}

void ADC_init(void)
{
  ADC_CSR = 0x03;            // ADC输入引脚AIN3
  ADC_CR1 = 0x01;            // ADC开启
}

void UART3_init(void)
{
  UART3_BRR2 = 0x01;
  UART3_BRR1 = 0x34;         // 8M/9600 = 0x341
  UART3_CR2 = 0x0C;          // 允许接收,允许发送
}

void init_devices(void)
{
  asm("sim");
  CLK_init();
  GPIO_init();
  EXTI_init();
  ADC_init();
  UART3_init();
  asm("rim");
}

void main( void )
{
  init_devices();

// 主循环里没有程序需要执行
  while(1);
}

在本例中仅使用了ADC的单次转换模式,每按一次按键进行一次AD转换,并把转换结果通过UART发送,这样可以在电脑上通过超级终端或串口调试软件查看数据。

通过这次测试,还发现一个现象,如果把清除EOC转换结束标志放在读取数据之后,那么在下次启动单次转换后,EOC标志位会自动置位,此时必须人为的等待7us后才能读到正确的数据,否则只能读到上一次的转换数据,可能这是STM8的ADC与其他MCU不同之处。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则