走过路过千万不要一笑而过……
向路过的各位大侠请教个问题:
小弟菜鸟只学过51汇编,没有学过C,没有学过AVR
现在要用到AVR,遇到点麻烦,请大侠帮帮忙,谢谢。。。
初来咋到,分不多,大家别嫌少,帮帮忙,3Q
atmega16和12位ADC的SPI通信,我弄了半天,也没有弄通,请大家帮忙看看程序:
ADC芯片资料在附件:
mcp3204.pdf
(1.44 MB)
mega16芯片:
mega16-16L_cn.pdf
(2.83 MB)
菜鸟的程序:
AVR硬件SPI:
unsigned char Get_mcp3204_val(void)
{
unsigned int i;
float j;
i = mcp3204_SPI();
j = (i*5)/4096;
//这里只取转换结果整数部分验证一下通信是否成功先
j = (unsigned char)j;
return(j);
}
unsigned int mcp3204_SPI(void)
{
unsigned int temp,temp1;
DDRB =(1<<PB7)|(~(1<<PB6))|(1<<PB5)|(1<<PB4);
PORTB = (1<<PB7)|(1<<PB6)|(~(1<<PB5))|(1<<PB4);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0);//
PORTB &=(~(1<<PB4));//启动通信
SPSR = 0x00;
SPDR = 0x07;//发送起始位和SGL,D2位
while(!SPSR&(1<<SPIF));
PORTB &=(1<<PB4);
SPSR = 0x00;
SPDR = 0x3f;//发送D1D0
while(!SPSR&(1<<SPIF));
SPSR = 0x00;
temp = SPDR;//接受高四位
while(!SPSR&(1<<SPIF));
SPSR = 0x00;
temp1 = SPDR;//接受低8位
while(!SPSR&(1<<SPIF));
PORTB &=(1<<PB4);
temp = (unsigned int)temp<<8;
temp = (unsigned int)((temp|temp1)&0x0fff);
return(temp);
}
软件模拟SPI:
#include<avr/io.h>
#include"delay.h"
#include"display.h"
#define CS PB4
#define DO PB6
#define DI PB5
#define CLK PB7
unsigned int SPI_mcp3204(void);
int main(void)
{
while(1)
{
unsigned char temp;
unsigned int m,n;
m = SPI_mcp3204();
n = (m*5)/4096;
temp = (unsigned char)n;
display(temp);
}
}
unsigned int SPI_mcp3204(void)
{
unsigned char j;
unsigned int i = 0;
DDRB = 0xbf;
PORTB = 0xff;
//发送启动位和SGL,D2,D1,D0
PORTB &=(~(1 << CS));
PORTB &=(~(1 << CLK));
PORTB &= (1<< DI);//1
PORTB &=(1 << CLK);
asm("nop");
PORTB &=(~(1 << CLK));
PORTB &= (1<< DI);//1
PORTB &=(1 << CLK);
asm("nop");
PORTB &=(~(1 << CLK));
PORTB &=(~(1 << DI));//0
PORTB &=(1 << CLK);
asm("nop");
PORTB &=(~(1 << CLK));
PORTB &=(~(1 << DI));//0
asm("nop");
PORTB &=(1 << CLK);
//采样周期
asm("nop");
PORTB &=(~(1 << CLK));
asm("nop");
PORTB &=(1 << CLK);
//空位
asm("nop");
PORTB &=(~(1 << CLK));
asm("nop");
PORTB &=(1 << CLK);
//读取转换结果
for(j =12;j > 0; j--)
{
asm("nop");
PORTB &=(~(1 << CLK));
asm("nop");
i = ((PINB&0x40) >> PB6);
i <<=1;
PORTB &=(1 << CLK);
}
PORTB &= (1 << CS);//拉高片选
i >>= 1;
return(i);
} |