C程序与汇编

这个程序的目的是从内存中读取10个字节,将它们转换为十六进制字符,并通过显示设备输出这些字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#define DISP_DATA (volatile char *) 0x4010 // 定义显示数据寄存器的地址
#define DISP_STATUS (volatile char *) 0x4014 // 定义显示状态寄存器的地址
#define LOC (char *) <arbitrary address> // 定义数据存放的位置

/* 十六进制字符转换查找表 */
char table[] = {
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // '0'-'7'
0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 // '8'-'F'
};

void main() {
char ch, byte, *byte_ptr; // 定义字符变量和指针
int i; // 循环计数器
byte_ptr = LOC; // 设置字节的起始地址

for (i = 0; i < 10; i++) { // 循环显示10个字节
byte = *byte_ptr; // 从内存读取下一个字节
ch = table[(byte >> 4) & 0xF]; // 转换高4位为字符
while ((*DISP_STATUS & 0x4) == 0); // 等待显示设备准备好
*DISP_DATA = ch; // 将字符传输到显示设备

ch = table[byte & 0xF]; // 转换低4位为字符
while ((*DISP_STATUS & 0x4) == 0); // 等待显示设备准备好
*DISP_DATA = ch; // 将字符传输到显示设备

ch = 0x20; // 空格字符用于分隔显示的字节
while ((*DISP_STATUS & 0x4) == 0); // 等待显示设备准备好
*DISP_DATA = ch; // 将空格字符传输到显示设备

++byte_ptr; // 指向下一个字节
}
}

程序详细解释

  1. 寄存器定义
    • DISP_DATADISP_STATUS 是指向特定内存地址的指针,分别用于访问显示数据和显示状态的寄存器。这些地址是硬件相关的,用于控制和监控显示设备的状态。
  2. 查找表
    • table 数组是一个查找表,用于将数字(0-15)转换为其对应的ASCII字符('0'-'9' 和 'A'-'F')。例如,table[0] 对应字符 '0',table[10] 对应字符 'A'。
  3. 主函数
    • void main() 是程序的入口点。
    • char ch, byte, *byte_ptr; 定义了字符变量和指针,byte_ptr 用于指向内存中的字节位置。
    • byte_ptr = LOC;byte_ptr 初始化为指向预定义的内存位置(LOC)。
  4. 循环显示字节
    • for (i = 0; i < 10; i++) 开始一个循环,目的是读取和显示10个字节。
    • byte = *byte_ptr; 从当前字节位置读取一个字节。
    • ch = table[(byte >> 4) & 0xF]; 将读取的字节的高4位转换为相应的字符。byte >> 4 将字节右移4位,得到高位,& 0xF 仅保留低4位。
    • while ((*DISP_STATUS & 0x4) == 0); 这是一个阻塞等待循环,直到显示设备准备好接收数据(即状态寄存器的特定位被置为1)。
    • *DISP_DATA = ch; 将转换得到的字符传输到显示设备。
    • ch = table[byte & 0xF]; 处理低4位,使用相同的方法将低4位转换为字符并传输。
    • ch = 0x20; 设置字符为空格(ASCII码为0x20),用于分隔显示的字节。
    • 最后,++byte_ptr; 将指针指向下一个字节。

这个程序的目的是从内存中读取一个32位的无符号整数,并逐位显示其二进制表示(即显示每一位是0还是1)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define DISP_DATA (volatile char *) 0x4010 // 定义显示数据寄存器的地址
#define DISP_STATUS (volatile char *) 0x4014 // 定义显示状态寄存器的地址
/* 假设16位数量存储在32位字中 */
#define BINARY (unsigned int *) <arbitrary address> // 定义存储二进制数据的地址

void main() {
char ch; // 定义字符变量
unsigned int *binary_ptr, binary_value, bit; // 定义指针和变量

binary_ptr = BINARY; // 将指针初始化为指向数据的地址
binary_value = *binary_ptr; // 从内存读取数据

for (int i = 15; i >= 0; i--) { // 循环显示16位
bit = binary_value >> i; // 右移以孤立下一个位
if (bit == 0) // 根据位的值确定显示字符
ch = '0';
else
ch = '1';

while ((*DISP_STATUS & 0x4) == 0); // 等待显示设备准备好
*DISP_DATA = ch; // 将字符传输到显示设备
}
}

程序详细解释

  1. 寄存器定义
    • DISP_DATADISP_STATUS 是指向特定内存地址的指针,用于访问显示数据和显示状态寄存器。这些地址通常与硬件相关,用于控制显示设备。
  2. 数据地址定义
    • #define BINARY (unsigned int *) <arbitrary address> 定义了一个指向32位无符号整数的指针,用于指向存储16位数量的内存位置。虽然程序只处理16位,但存储在32位字中。
  3. 主函数
    • void main() 是程序的入口点。
    • char ch; 定义了一个字符变量 ch,用于存储要显示的字符。
    • unsigned int *binary_ptr, binary_value, bit; 定义了一个指向无符号整数的指针 binary_ptr,一个无符号整数变量 binary_value 用于存储读取的值,和一个无符号整数变量 bit 用于存储当前位的值。
  4. 指针初始化
    • binary_ptr = BINARY; 将指针 binary_ptr 初始化为指向预定义的内存地址(BINARY)。
    • binary_value = *binary_ptr; 通过解引用指针读取内存中的数据,并将其存储在 binary_value 中。
  5. 循环显示位
    • for (int i = 15; i >= 0; i--) 开始一个循环,显示16位。这里的循环从15开始,逐渐减少到0。
    • bit = binary_value >> i; 通过右移操作提取当前位(从最高位到最低位)。右移操作使得每次循环时,当前位的值存储在 bit 变量中。
    • if (bit == 0) 根据提取的位的值决定要显示的字符。如果 bit 等于0,则将字符设置为'0',否则设置为'1'。
    • while ((*DISP_STATUS & 0x4) == 0); 这是一个阻塞等待循环,直到显示设备准备好接收数据。只有在状态寄存器的特定位被置为1时,程序才会继续执行。
    • *DISP_DATA = ch; 将字符('0' 或 '1')传输到显示设备进行显示。

这个程序的目的是使用定时器和7段显示器循环显示数字0到9,每秒更新一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define TIM_STATUS (volatile char *) 0x4020 // 定义定时器状态寄存器的地址
#define TIM_CONT (volatile char *) 0x4024 // 定义定时器控制寄存器的地址
#define TIM_INIT (volatile int *) 0x4028 // 定义定时器初始化寄存器的地址
#define SEVEN (volatile char *) 0x4030 // 定义7段显示器的地址
/* 假设定时器的时钟频率为100 MHz */
#define ONE_SECOND_COUNT 0x05F5E100 // 定义1秒的计数值
/* 包含7段显示所需模式的表 */
char table[] = {
0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
0x7F, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void main() {
int digit; // 定义显示的数字
char pattern; // 定义显示模式
*TIM_INIT = ONE_SECOND_COUNT; // 设置1秒延迟的计数周期
*TIM_CONT = 6; // 设置连续模式
digit = 0; // 初始化要显示的数字

while (1) { // 无限循环
while ((*TIM_STATUS & 2) == 0); // 等待1秒周期结束
pattern = table[digit]; // 将数字转换为7段显示模式
*SEVEN = pattern; // 在7段显示器上显示模式
digit = digit + 1; // 增加数字计数
if (digit > 9) // 如果数字超过9则重置计数器
digit = 0;
}
}

程序详细解释

  1. 寄存器定义
    • TIM_STATUSTIM_CONTTIM_INIT 是指向特定内存地址的指针,分别用于访问定时器的状态寄存器、控制寄存器和初始化寄存器。这些寄存器通常与硬件相关,用于控制和监测定时器的行为。
    • SEVEN 定义了一个指向7段显示器的地址。
  2. 常量定义
    • #define ONE_SECOND_COUNT 0x05F5E100 定义了1秒钟的计数值。假设定时器时钟频率为100 MHz,所以1秒对应的计数值为 100000000,以16进制表示为 0x05F5E100
  3. 7段显示模式表
    • char table[] 定义了一个包含7段显示器各个数字(0-9)及其它模式(如空白)的数组。每个元素对应于一个数字的7段显示模式。
  4. 主函数
    • void main() 是程序的入口点。
    • int digit; 定义了一个整数变量 digit,用于存储当前要显示的数字。
    • char pattern; 定义了一个字符变量 pattern,用于存储7段显示器的显示模式。
  5. 定时器初始化
    • *TIM_INIT = ONE_SECOND_COUNT; 将定时器初始化寄存器设置为1秒的计数值,配置定时器以便它能在每秒后产生一个信号。
    • *TIM_CONT = 6; 将定时器控制寄存器设置为6,开启连续模式,这样定时器将在每次计数完后自动重新开始。
  6. 无限循环
    • while (1) { 开始一个无限循环,程序将持续运行。
    • while ((*TIM_STATUS & 2) == 0); 这个内层循环检查定时器状态寄存器的特定位是否被置为1,表示1秒计数已经结束。程序将一直等待,直到这个条件满足。
    • pattern = table[digit]; 通过 digit 变量从 table 数组中获取对应的7段显示模式。
    • *SEVEN = pattern; 将得到的模式传输到7段显示器上进行显示。
    • digit = digit + 1; 每次更新后,将数字计数器加1。
    • if (digit > 9) 如果 digit 超过9,表示已经显示完数字0-9,程序将重置 digit 为0,以便循环显示。

这个程序的目的是使用两个7段显示器循环显示数字00到99,每秒更新一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#define TIM_STATUS (volatile char *) 0x4020 // 定义定时器状态寄存器的地址
#define TIM_CONT (volatile char *) 0x4024 // 定义定时器控制寄存器的地址
#define TIM_INIT (volatile int *) 0x4028 // 定义定时器初始化寄存器的地址
#define SEVEN (volatile short *) 0x4030 // 定义两个7段显示器的地址
/* 假设定时器的时钟频率为100 MHz */
#define ONE_SECOND_COUNT 0x05F5E100 // 定义1秒的计数值
/* 包含7段显示所需模式的表 */
char table[] = {
0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
0x7F, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void main() {
int digit1, digit0; // 定义两个数字用于显示
short pattern; // 定义显示模式
*TIM_INIT = ONE_SECOND_COUNT; // 设置1秒延迟的计数周期
*TIM_CONT = 6; // 设置连续模式
digit1 = 0; // 初始化高位数字
digit0 = 0; // 初始化低位数字

while (1) { // 无限循环
while ((*TIM_STATUS & 2) == 0); // 等待1秒周期结束
pattern = (table[digit1] << 8) | table[digit0]; // 将两个数字转换为7段显示模式
*SEVEN = pattern; // 在7段显示器上显示模式
digit0 = digit0 + 1; // 增加低位数字计数
if (digit0 > 9) { // 如果低位数字超过9,则重置
digit0 = 0; // 重置低位数字
digit1 = digit1 + 1; // 增加高位数字计数
if (digit1 > 9) { // 如果高位数字超过9,则重置
digit1 = 0; // 重置高位数字
}
}
}
}

程序详细解释

  1. 寄存器定义
    • TIM_STATUSTIM_CONTTIM_INIT 是指向特定内存地址的指针,分别用于访问定时器的状态寄存器、控制寄存器和初始化寄存器。这些寄存器通常与硬件相关,用于控制和监测定时器的行为。
    • SEVEN 定义了一个指向两个7段显示器组合的地址,使用 short 类型来表示16位的整数,因为两个7段显示器可以共同使用一个16位的数据寄存器。
  2. 常量定义
    • #define ONE_SECOND_COUNT 0x05F5E100 定义了1秒钟的计数值。假设定时器时钟频率为100 MHz,所以1秒对应的计数值为 100000000,以16进制表示为 0x05F5E100
  3. 7段显示模式表
    • char table[] 定义了一个包含7段显示器各个数字(0-9)及其它模式(如空白)的数组。每个元素对应于一个数字的7段显示模式。
  4. 主函数
    • void main() 是程序的入口点。
    • int digit1, digit0; 定义了两个整数变量 digit1digit0,分别用于表示高位和低位的数字(显示的两个数字)。
    • short pattern; 定义了一个短整型变量 pattern,用于存储两个7段显示器的显示模式。
  5. 定时器初始化
    • *TIM_INIT = ONE_SECOND_COUNT; 将定时器初始化寄存器设置为1秒的计数值,配置定时器以便它能在每秒后产生一个信号。
    • *TIM_CONT = 6; 将定时器控制寄存器设置为6,开启连续模式,这样定时器将在每次计数完后自动重新开始。
  6. 无限循环
    • while (1) { 开始一个无限循环,程序将持续运行。
    • while ((*TIM_STATUS & 2) == 0); 这个内层循环检查定时器状态寄存器的特定位是否被置为1,表示1秒计数已经结束。程序将一直等待,直到这个条件满足。
    • pattern = (table[digit1] << 8) | table[digit0]; 通过 digit1digit0 变量从 table 数组中获取对应的7段显示模式。这里使用左移操作将高位数字的模式移到高字节,再通过按位或(|)操作将低位数字的模式合并,形成一个16位的显示模式。
    • *SEVEN = pattern; 将得到的模式传输到7段显示器上进行显示。
    • digit0 = digit0 + 1; 每次更新后,将低位数字计数器加1。
    • if (digit0 > 9) 如果 digit0 超过9,表示已经显示完数字0-9,程序将重置 digit0 为0,并将高位数字 digit1 加1。
    • if (digit1 > 9) 如果 digit1 超过9,表示已经显示完数字00-99,程序将重置 digit1 为0。