问个菜鸟问题,马老师的书187页.关于把一字节数据由低到高输出到hc164上.
看书自学avr买了开发板觉得挺有兴趣的,在187页遇到了一个搞不懂的问题.程序运行成功了但是有个疑问总也想不明白,请明白人指点一下吧.
不相关的我就省略了.
#define HC164_data PORTA.0
#define HC164_clk PORTA.1
void HC164_send_byte(char byte)//定义函数 吧一个字节的数据串行发送到74hc164 程序运行成功了.
{
char i;
for(i=0;i<=7;i++)
{
HC164_data=byte&1<<i;
HC164_clk=1;
HC164_clk=0;
}
}
HC164_data=byte&1<<i; 这句有些搞不懂假设byte=0xff i=0-7的话那么HC164_data 应该分别 为00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000我真的是刚入门的我都不知道我算的对不对,如果正确的话.PORTA.0每次只有2种状态但是00000001是八位的.就这个地方想不明白了.我想把所有的程序都理解了在往下做实验.知道的请指点下.多谢! 先学习或复习C语言的基本知识,回答下面的问题:
for(i=0;i<=7;i++)
{
if (0x5a & 1<<i)
{
语句1;
}
else
{
语句2;
}
}
在这个循环中,语句1执行几次?语句2执行几次?这2个语句分别在什么条件时执行的?
i 执行(1 or 2)?
---------------------------
0 语句?
1 语句?
2 语句?
3 语句?
4 语句?
5 语句?
6 语句?
7 语句? there are multiple issues with the code:
1) using (1<<i) isn't very efficient. using a mask (i=0x01) for example, would speed up the speed considerably;
2) if you read hc164's data sheet, the data is shifted in on the rising edge of sck.
"HC164_data=byte&1<<i; 这句有些搞不懂假设byte=0xff i=0-7的话那么HC164_data 应该分别 为00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000 "
since the code is to shift the least significant bit first, as i starts from 0 (contrary to the spi protocol), the first bit in is byte's least significant bit (0th bit).
if you still want to shift the least significant bit, I would suggest that you rewrite it as follows:
void HC164_send_byte(unsigned char byte)//定义函数 吧一个字节的数据串行发送到74hc164 程序运行成功了.
{
unsigned char i=0x01; //shift out the least significant bit first
//for(i=0;i<=7;i++)
do
{
HC164_clk=0; //clear clk
HC164_data=byte&i; //set sdi
HC164_clk=1; //set clk -> strobe data out on the rising edge
i = i << 1; //send the next bit
} while (i); //wait until all bits are sent
}
hope it helps. 多些马老师和millwood0 的解答。
看来我对基础知识的掌握存在不少问题。
先答题。
循环中if (0x5a & 1<<i) 如果表达式的值为真执行 语句1 否者执行 语句2
0x5a 二进制 01011010
那么按位跟1进行与操作的结果中有4次返回非0的值(我一直以为1才是真,原来非0才是真)。
语句1执行4次,语句2执行4次。
i 执行(1 or 2)?
---------------------------
0 语句2
1 语句1
2 语句2
3 语句1
4 语句1
5 语句2
6 语句1
7 语句2
不知道我回答的对么。
然后到这里我突然想到了。是不是在avr的c语言中PORTA.0=因为这个代表一个端口只有2种状态,那么等号后面的表达式也想if语句一样只返回真或者假的值而不是一个8位的数据.
PORTA.0=00010000 这时前面的数据被判断真或者假而不是具体的8位2进制数,因为一个端口只有2种状态。
PORTA=00010000 这个就代表8个端口的状态。
这些规则都是由头文件来定义的么?不知道我理解的对不对。 还是基础概念的问题。
在任何的程序设计语言中,判断语句的定义是:IF(逻辑表达式),其中逻辑表达式的值只可能为“1”或“0”。
在 if (0x5a & 1<<i)语句中,括号中看上去是数值表达式,不是逻辑表达式,但由于IF ()的规定,这个数值表达式的结果必须转换成逻辑值。
按规定,当数值表达式的值不为另,其转换成逻辑值为“1”,只有数值表达式的值为另,其转换成逻辑值为“0”。
这里隐含了一个数据类型转换的操作。这个在学习C语言中的表达式计算和赋值语句都会讲到的。是基本概念。
=========================================
在LZ位代码中:
HC164_data = byte&1<<i;
HC164_data是BIT型变量,在标准C中是没有这个类型变量的,它是CVAVR中扩展的。这个BIT型变量,相当逻辑变量,只能有2个值“0”/“1”。赋值号右面是数值表达式,其结果是数值型值,但要赋给BIT型变量,就需要进行类型转换。这个转换也是隐含的,规则同转换为逻辑值相同。
这种情况在许多地方会用到的,例如:
int a = 0xaa55;
char b;
b = a;
此时b的值是多少?
而执行 b = a >> 8;后,b的值有是多少?这条语句同b = a / 256;有什么区别?
不要认为结果相同就没有区别,如果具备汇编的概念,你就知道应该用哪个更好了。
直接面向硬件的程序员是特殊的程序员,使用的许多语句是高效率的,但对于普通程序员来讲是不容易理解的。 "循环中if (0x5a & 1<<i) 如果表达式的值为真执行 语句1 否者执行 语句2 "
that's a bad way of coding.
this is better:
"if (0x5a & (1 << i))": it uses the brackets to force the priority.
"PORTA.0=00010000 这时前面的数据被判断真或者假而不是具体的8位2进制数,因为一个端口只有2种状态。 "
that's a terrible way of coding, as PORTA.0's value is compiler dependent: as PORTA.0 is a bit, some compilers will take 00010000's last bit (a 0) and assigned it ito PORTA.0; other compilers will take 00010000 and treat it as one, and assigned a 1 to PORTA.0. in general, you should avoid the use of bit variables - as they are generally not supported natively by the hardware - 8051 being the exception.
whenever possible, use a mask. 马老师,敬礼!!!!!!! mark 多谢马老师和millwood0 的热心解答.原来是这么基础性的问题.是我的底子太薄啦,我会继续努力的.
页:
[1]