要求:

在作业本上完成附图作业,要认真看题目要求并提交作业截图。

image

课上做错的内容:如下图所示
image

错误地点:1.主要是因为时间紧迫,把移位的位数搞错了。
2.与的写法写错为||,应该为|。

课上正确代码

void SetHours(int hours)

#define base 0xFFFFC0000 
#define &clock base+2
void SetHours(int hours)
{
clock = clock&~(0x1F);
clock = clock|(hour);
 }

  • 在set的过程中,我们需要将hour部分进行赋值,赋值我们采用“先清零”再“或运算”的方式,先和1111111111100000进行运算,将0-4位清零,其他位保证不变,再与hour进行“或运算”,最终就成功将hour加入时间变量里面。
#define base 0xFFFFC0000 

#define &clock base+2

int getHours(int hour)

{

second = clock &(0x1F);

return hour;

}
  • 在get的过程中,我们需要将除了hour以外的部分清零,所以先将hour右移11位,即0000000000011111与0X1F作“与运算”,剩下的正好是我们需要的值。

课下补充学习:

1. C语言对寄存器的操作

在嵌入式开发中,我们需要对寄存器进行写入,读出等等操作。每个寄存器都有自己固有的地址,我们需要通过C语言访问这些地址。

#define Time_Addr 0xFFFFC0000;
#define Time        *(volatile  int *)(Time_Addr+2)

也可以像我在作业中写的一样

#define Time        *(volatile  int *)(0xFFFFC0002)

两种方法都是可以的。

其中关于volatile
volatile是一个类型修饰符(type specifier),就像大家更熟悉的const一样,它是被设计用来修饰被不同线程访问和修改的变量。volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

首先(volatile int)是一个指针,我们就假设它为p吧。它存储的地址就是后面的(Time_Addr+2),然后取这个地址的值,也就是p,接下来我们就能直接赋值给Time来改变地址上(Time_Addr+2)存储的值了。

2.关于提取位与插入位(均以分钟为例)

提取位
image
插入位
image

其中秒占了五位,故将时间右移5位,这时我们要将它提取出来,故要将每位&1,即&0x3F。

延伸(提取秒)

#define base 0xFFFFC000
#define &clock base+2 

void setSecond(int second){
    clock = clock & 0xFFF0;
    clock = second|clock;
}

int getSecond(){
    return ((int)clock & 0x000F);
}