打印
[AVR单片机]

那位用mega8驱动过max6675,硬件spi

[复制链接]
2435|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chuandaoxy|  楼主 | 2024-4-9 08:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
搜了一下网上的驱动模拟spi居多,硬件的spi有个俄罗斯大兄弟做过,输出数据不对,大家看看哪里错了,我想借鉴一下他的框架,使用硬件spi

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include "max6675.h"
#include "LCD.h"

uint16_t gettemp(void); //Funktionsdeklarationen
void initavr(void);

//gettemp () returns absolute Temperature in Temp * 4 °C - in 1/4°-steps
//
uint16_t gettemp(void){ //Temperatur holen.
uint8_t bit = 0, bitnr = 12; //Variablen
uint8_t foo1 = 0;
uint16_t Rohdata = 0;

CS_Port &= ~(1 << CS); //Chip select anlegen

for(foo1 = 0 ; foo1 < 16 ; foo1++){ //16 Bits einlesen
bit = 15 - foo1; //Die Aktuelle Bitnr berechnen.

SCK_Port |= (1 << SCK); //SCK hi

if((bit <= 14) && (bit >= 3)){ //Einfach mal die 12 relevanten von den 16 Bits ausfiltern
if((SO_Pin & (1 << SO))){ //WENN SO 1 ist, dann...
bitnr--; //zдhlen wir runter...
Rohdata |= (1 << bitnr); // und schieben eine 1 an bit x
}else{ //WENN dem NICHT so ist, dann...
bitnr--; //zдhlen wir runter...
Rohdata &= ~(1 << bitnr); //und schieben eine 0 an bit x
}
}else{ //weis au nimmer, was das soll.
bitnr = 12;
}

SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.

return Rohdata; //Das ist doch mal was ;D
}

// getTC() returns 0 if Thermocouple is not connected, 255 if thermocuple is connected
// (to enable this feature T- must be connected to GND)
uint8_t getTC(void){ //Temperatur holen. //Variablen
uint8_t TC = 0;
uint8_t foo1 = 0;

CS_Port &= ~(1 << CS); //Chip select anlegen

for(foo1 = 0 ; foo1 < 16 ; foo1++){ //16 Bits einlesen //Die Aktuelle Bitnr berechnen.

SCK_Port |= (1 << SCK); //SCK hi

if(foo1 == 2){ //das 3. bit ist fьr uns relevant.
if((SO_Pin & (1 << SO))){ //WENN SO 1 ist, dann...
TC = 0;
}else{ //WENN dem NICHT so ist, dann...
TC = 255;
}
}
SCK_Port &= ~(1 << SCK); //SCK LO
}
CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.

return TC; //Das ist doch mal was ;D
}

//Initiates the MAX6675 and IO-pins
void init_6675(void){ //AVR initialisieren

SO_DDR &= ~(1 << SO);
CS_DDR |= (1 << CS);
SCK_DDR |= (1 << SCK); //IOs setzen

SO_Port |= (1<<SO); //Pullups an. (Wichtig fьr MAX6675, der kann nicht anders, hab ich festgestellt...

CS_Port |= (1 << CS); //CS HI //Alles auf Standardkonfig.
SCK_Port &= ~(1 << SCK); //SCK LO

}

int main(void)
{
init_port();// инициализируем порт ЖКИ
lcd_init();// инициализируем ЖКИ
init_6675();



while (1)
{
                char buffer[8];
int temp;
temp = gettemp();
temp /=4;


lcd_gotoxy(0,0);//перемещаем курсор в верхний левый угол
sprintf(buffer, "t=%i\xdf\C ", temp); // так как тут не плавающая запятая то числа с запятой записываются так %i.%i, код градуса записывается так \xdf
lcd_putstring(buffer);
}


}

使用特权

评论回复

相关帖子

沙发
minfugan| | 2024-4-10 17:50 | 只看该作者
单片机在SCK下降沿读数。把gettemp()和getTC()里的时钟信号管脚——SCK_Port |= (1 << SCK); //SCK hi——置1后延时一段时间,把时钟信号管脚——SCK_Port &= ~(1 << SCK); //SCK LO——清零后再读数,注意时钟的电平稳定时间要超过100ns。

使用特权

评论回复
板凳
zhanan| | 2024-4-13 14:38 | 只看该作者
本帖最后由 zhanan 于 2024-4-13 14:39 编辑

写这么复杂,软件模拟的吧。硬件的配置好端口,启动,等中断(或中断标志)即可。

使用特权

评论回复
地板
zhanan| | 2024-4-13 14:53 | 只看该作者
软件模拟,在时钟上跳后及时钟下跳前的时间内读取,高位先读。D14-D3是数据位,D4D3小数位,D2是断线位。
    CS=0; // 拉低片选
    temp=0;
    for(nxh=0;nxh<16;nxh++)
    {
      SCK=1;   // 发SCK
      temp<<=1; if(SO) temp|=1; // 读一位,高位先
      SCK=0;
    }
    CS1=1; // 释放片选,开始新的转换

使用特权

评论回复
5
zhanan| | 2024-4-13 14:54 | 只看该作者
软件模拟,在时钟上跳后及时钟下跳前的时间内读取,高位先读。D14-D3是数据位,D4D3小数位,D2是断线位。
    CS=0; // 拉低片选
    temp=0;
    for(nxh=0;nxh<16;nxh++)
    {
      SCK=1;   // 发SCK
      temp<<=1; if(SO) temp|=1; // 读一位,高位先
      SCK=0;
    }
    CS1=1; // 释放片选,开始新的转换

使用特权

评论回复
6
zhanan| | 2024-4-13 14:57 | 只看该作者
卡了一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

855

主题

1044

帖子

4

粉丝