【问题标题】:Need explain a code in embedded program需要在嵌入式程序中解释代码
【发布时间】:2014-01-31 16:30:27
【问题描述】:

我对嵌入式编程完全陌生,我正在检查下面的代码并试图了解它是如何工作的,但我真的被卡住了。

该程序用于计算并打印出0到9的数字。

那么有人可以解释一下const uint8_t这行吗?为什么我需要一个十六进制数的数组?

#include <avr/io.h>
#include <util/delay.h>
#include "debug.h"


const uint8_t segments[10] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6};

int main(void) {
    uint8_t i=0; //s
    int g; 
    init_debug_uart0();
    /* set PORT A pins as outputs */
    DDRA = 0xFF;
    for (;;) {

        PORTA = segments[i]; 
        printf("%d\n\r",i); 
        _delay_ms(1000);

        if (i >=9) {
            fprintf(stderr , "Count Overflow\n\r"); i = 0;
            scanf("%d", &g);
        }else 
            i++;
    }
}

最后一个问题,有没有人知道关于嵌入式编程的好资料?目前我正在学习 IIMatto,8 位处理器,它有 32 个寄存器,采用哈佛架构设计,有 1 级流水线。

【问题讨论】:

  • 查看您的原理图以查看连接到端口 A 的内容,然后查看这些十六进制常量的位模式。
  • 在我看来,它们可能是位模式,可以照亮 7 段显示器中的正确段。
  • @bobmcn - 嗯 - 你破坏了惊喜:)

标签: c embedded


【解决方案1】:

const uint8_t segments[10] = {0xFC,0x60,0xDA, ... 简单定义了一个恒定的 10 字节字节数组。

代码不需要十六进制数组,它可以是十进制。

但是考虑一下

的好处
0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE4,0xFE,0xF6
// versus
252,96,218,...

随便看看,每个字节设置的位数是

6,2,5,5,...

这恰好与数字 0、1、2、3 的 7 段显示中设置的段数相匹配 ...
仔细检查位设置将详细说明哪个位激活哪个段。

可以使用其他方法来获得这种 7 段到数字的映射,但以十六进制显示数据比十进制更接近一步。


也许代码可能是这样的(正确的段映射是待定)。

typedef enum  {
  LED7_a       = 1 << 0,
  LED7_b       = 1 << 1,
  LED7_c       = 1 << 2,
  LED7_d       = 1 << 3,
  LED7_e       = 1 << 4,
  LED7_f       = 1 << 5,
  LED7_g       = 1 << 6,
  LED7_dp      = 1 << 7
  } LED7_Segment_t;

/* ****************************************************************************
7 Segment Pattern
 Layout
  aaa
 f   b
 f   b
  ggg
 e   c
 e   c
  ddd dp
**************************************************************************** */
const uint8_t segments[] = {
  /*'0*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f         ,
  /*'1*/          LED7_b | LED7_c                                    ,
  /*'2*/ LED7_a | LED7_b |          LED7_d | LED7_e |          LED7_g,
  /*'3*/ LED7_a | LED7_b | LED7_c | LED7_d |                   LED7_g,
  /*'4*/          LED7_b | LED7_c |                   LED7_f | LED7_g,
  /*'5*/ LED7_a |          LED7_c | LED7_d |          LED7_f | LED7_g,
  /*'6*/ LED7_a |          LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
  /*'7*/ LED7_a | LED7_b | LED7_c                                    ,
  /*'8*/ LED7_a | LED7_b | LED7_c | LED7_d | LED7_e | LED7_f | LED7_g,
  /*'9*/ LED7_a | LED7_b | LED7_c | LED7_d |          LED7_f | LED7_g};

【讨论】:

    【解决方案2】:

    首先,问问自己在哪里segments被使用了,什么它是用来做什么的,它是如何使用的的? p>

    提示:

    其中:用于为PORTA赋值

    什么: PORTA 是一个嵌入式系统的输出。也许到外部设备。 segments 用于存储输出。

    如何:每次循环时,i 的值都会递增。当i 的值分配给PORTA 时,i 用作segments 的索引。

    另外:十六进制数,特别是 2 位长,是一个 8 位的字节。在您的微控制器上查看最多 8 个标有“PORTA”的引脚

    【讨论】:

      【解决方案3】:

      当写入 PORTA(一个 I/O 端口)时,您关心的是与每个位相关联的各个 I/O 线的状态。

      要在 7 段显示器上显示代表一个数字的一​​组特定段,您必须编写一个特定的位模式 - 您希望点亮的每个段对应一个位。 segments 数组由您要显示的数字索引,该索引处的值表示 PORTA 上点亮代表该数字的段所需的位模式。

      使用十六进制的原因是因为有一个十六进制数字直接映射到四个二进制数字,所以十六进制是表示位模式的一种紧凑方式。对于经验丰富的嵌入式开发人员来说,将位模式转换为十六进制(反之亦然)成为第二天性。如果这些值是十进制的,则表示将与位模式没有直接关系,并且位模式的转换或心理可视化就不那么简单了。

      十六进制数字到二进制模式的转换如下:

      0 0000
      1 0001
      2 0010
      3 0011
      4 0100
      5 0101
      6 0110
      7 0111
      8 1000
      9 1001
      A 1010
      B 1011
      C 1100
      D 1101
      E 1110
      F 1111
      

      【讨论】:

        【解决方案4】:
        0xFC = 11111100
        0x60 = 1100000
        0xDA = 11011010
        ....
        

        你需要一个十六进制数字数组,很可能你已经将某种设备连接到端口A,并且在这个设备中

        0xFC or 11111100 means display 0,(when portA pins 7,6,5,4,3,2, are high and 1,0 are low     this device will display 0
         0x60 or 11000000 means display 1(when PortA pins 7,6 are high and the rest low, this device will display 1. 
        

        等等..

        微控制器中的内存位置为 8 位 宽,因此 16 个 I/O 将需要两个 8 位寄存器,称为 PORTA 和 PORTB。在你的情况下,它只有 8 位宽,即。每个 PORTA 有 8 个 I/O 引脚,另外 8 个用于 PORTB,依此类推。

        这些端口的输出由 8 位控制..

        假设我们希望打开一个 LED,我们将连接到 PORTB 上的第 4 位。我们首先必须指示微控制器确保 PORTB 位 4 是输出。(微需要知道端口是否是输出,是输入,你不能只是插入东西)

        在 pic micro 你会说 TRIA = 0x00010000 这告诉 micro portB4 是一个输出。现在我们已经说它是一个输出,PORTA = 0b00010000 将此 portB4 设置为高电压,换句话说,这将点亮 LED或任何你连接到端口的东西。

        PORTA = 0b00000000 // 关闭 PORTA 输出, PORTA = 0b10000000 // 打开 PORTA 引脚 7

        【讨论】:

          【解决方案5】:

          十六进制值只是一个符号,第一个字母代表 int 的前 4 位,其他 4 位,因为您正在声明一个 const uint8 变量,这意味着 8 位的无符号整数,这是一个整数但是没有符号,符号的位被删除,所以它可以存储2^8个可能的值。

          我只是回答第一个问题。希望有帮助!!

          【讨论】:

          • 嗯,是的,这就是为什么它用十六进制表示。但是您可以尝试解释一下该表的用途是什么。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多