|
发表于 2011-11-18 21:59:20
|
显示全部楼层
here is a quick exercise that I did.
=============example================
#include <ioavr.h> //we use iar avr
//hardware configuration
#define HC164_PORT PORTE
#define HC164_DDR DDRE
#define HC164_CLK (1<<0)
#define HC164_MOSI (1<<1)
#define HC164_CLK_PIN PORTE_Bit0
#define HC164_MOSI_PIN PORTE_Bit1
//end hardware configuration
void hc164_init(void) {
HC164_PORT &=~(HC164_CLK | HC164_MOSI); //clear clk/mosi
HC164_DDR |= (HC164_CLK | HC164_MOSI); //clk / mosi as output
}
void hc164_write(unsigned char dat) {
unsigned char mask = 0x80; //mask, msb first
//HC164_PORT &=~(HC164_CLK | HC164_MOSI); //clear clk/mosi
//HC164_DDR |= (HC164_CLK | HC164_MOSI); //clk / mosi as output
do {
HC164_PORT &=~HC164_CLK; //clear clk
if (dat & mask) HC164_PORT |= HC164_MOSI; //send 1
else HC164_PORT &=~HC164_MOSI; //send 0
HC164_PORT |= HC164_CLK; //set clk
mask = mask >> 1; //send the next bit
} while (mask); //send all bits
//HC164_PORT &=~HC164_CLK; //reset clk - optional
}
void hc164_write2(unsigned char dat) {
unsigned char i;
for (i=0; i<8; i++) {
//HC164_MOSI_PIN = dat & (1<<i); //send bits
HC164_MOSI_PIN = (dat & (1<<i))? 1: 0;
HC164_CLK_PIN=1; //send clock
HC164_CLK_PIN=0; //clear clock
}
}
int main( void )
{
hc164_init(); //reset the hc164
//send 1st byte
HC164_PORT |= HC164_MOSI; //indicates the start of the transmission
hc164_write(0xaa); //send a byte
HC164_PORT |= HC164_MOSI; //indicates the end of the transmission
//send 2nd byte
HC164_PORT &=~HC164_MOSI; //indicates the start of the transmission
hc164_write2(0xaa); //send a byte
HC164_PORT &=~HC164_MOSI; //indicates the end of the transmission
while (1) {
}
return 0;
}
=========================
the above code implements two hc164 write routines, hc164_write() and hc164_write2().
hc164_write() uses masks and sends the most significant bit first, consistent with the spi standard.
hc164_write2() is your implementation - it uses a for () loop, and bit shifts and sends the least significant bit first.
*****notice that change I did in the particular implementation and I will come back there**********************
the hc164_write() sends the byte (0xaa) in 135us, and the bits show up correctly on hc164 (as 0xaa).
the hc164_write2() sends the byte (0xaa) in 470us, and the bits show up incorrectly on hc164 (as 0x55).
(原文件名:avr hc164.PNG) |
|