huangxiaolpbany 发表于 2013-3-29 11:04:36

MEGA16与TLC2543的SPI通信

用一个TLC2543(12bit、AD芯片带SPI)与MEGA16通信,使用SPI。
但是一直没有办法得到数据,MEGA16写TLC2543寄存器无法写入,用AVR STUDIO仿真,SPI里面的SPDR数据为0。
另外我将TLC2543设置为16bit输出,是否允许直接读两次SPI端口,先读出高8位,后读出低八位?
谢谢!

#include <macros.h>
#include <iom16v.h>
#define uint unsigned int
#define uchar unsigned char
#include "display.c"
uint ad;
uchar ad_l;


void spi_init()
{
       DDRB|=0XB0;
       PORTB|=BIT(4);
       SPCR=0X51;
       SPSR&=~BIT(0);//CLOCK=FOSC/16
}


uint tlc2543_con(uchar com)
{
   uchar status;
       PORTB&=~BIT(4);//CS=0,SLECTED
       SPDR=com;                                                                //仿真时SPDR数据不变
       
       //write data to tlc2543
       do
       {
             status=SPSR;
       }
       while(!(status&0X80));       
       PORTB|=BIT(4);
       
       delay(1);
       
       //read data from tlc2543
       PORTB&=~BIT(4);
       
       ad=SPDR;//D15-D8
       ad_l=SPDR;//D7-D0
       
       ad<<=8;
       ad|=ad_l;

       PORTB|=BIT(4);//CS=1
       
       
       return ad;
       
}

void main()
{
        uint speed_x;
        uchar i,dis;
        spi_init();//SPI bus initial
        for(i=0;i<2;i++)
        {
        speed_x=tlc2543_con(0X0C);//AD CONVERTER CHANNEL NO.0
        }
       
}

wmm20031015 发表于 2013-3-29 12:02:13

往里写8位数据+4位0,输出12位AD数据,这个数据是上一次的转换数据,SPI的速率建议不要低于1M,否则上升沿、下降沿不达标,得不到准确数据

yklstudent 发表于 2013-3-29 14:25:02

/*
* atmega16_spi_tlc2543.c
*
* Created: 2013/3/29 13:22:46
*Author: K.Yao
*/


#include <avr/io.h>
#ifndef F_CPU
#define F_CPU                4000000UL
#endif
#include <util/delay.h>
#include "bitwise.h"

#define EOC                SFR(PINB,0,1)
#define SS                SFR(PORTB,4,1)
#define SS1                SFR(PORTB,3,1)

#define MAX7221_Enable()        SS=0
#define MAX7221_Disable()        SS=1

#define TLC2543_Enable()        SS1=0
#define TLC2543_Disable()        SS1=1

typedef unsigned char uchar;
typedef unsigned intuint;
typedef unsigned long ulong;

void Port_Init(void)
{
        DDRB = 0b10111000;
}

void SPI_Init(void)
{
        SPSR = 0x00;
        SPCR = _BV(SPE)|_BV(MSTR)|_BV(SPR0);
}

uchar SPI_ReadAndWrite(uchar Dat)
{
        SPDR = Dat;
        while(!(SPSR&_BV(SPIF)));
        return (SPDR);
}

void MAX7221_WriteWord(uchar Addr,uchar Dat)
{
        MAX7221_Enable();
        SPI_ReadAndWrite(Addr);
        SPI_ReadAndWrite(Dat);
        MAX7221_Disable();
}

void MAX7221_Init(void)
{
        MAX7221_WriteWord(0x0A,0x07);
        MAX7221_WriteWord(0x0B,0x07);
        MAX7221_WriteWord(0x0C,0x01);
        MAX7221_WriteWord(0x0F,0x00);
        MAX7221_WriteWord(0x09,0xFF);
}

void MAX7221_Display(uchar *DispStr)
{
        for(uchar i=0;i<8;i++)
        {
                MAX7221_WriteWord(i+1,DispStr);
        }
}

uint TLC2543_ReadADValue(uchar channel)
{
        uint adc = 0;
        channel <<= 4;
        TLC2543_Disable();
        _delay_ms(3);
        TLC2543_Enable();
        while(0==EOC);
        TLC2543_Enable();
        adc |=        SPI_ReadAndWrite(0x0C|channel);
        adc <<= 8;
        adc |= SPI_ReadAndWrite(0x00);
        TLC2543_Disable();
        adc &= 0xFFF;
        return (adc);       
}

uchar DispTab[] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

int main(void)
{
        uint adc_value = 0;
        Port_Init();
        _delay_us(10);
        SPI_Init();
        _delay_ms(10);
        MAX7221_Init();
        _delay_us(10);
        MAX7221_Display(DispTab);
        _delay_us(10);
    while(1)
    {
                adc_value = TLC2543_ReadADValue(1);
                DispTab = 10;
                DispTab = 15;
                DispTab = 15;
                DispTab = adc_value/1000;
                DispTab = adc_value%1000/100;
                DispTab = adc_value%100/10;
                DispTab = adc_value%10;
                DispTab = 15;
                _delay_ms(20);
                MAX7221_Display(DispTab);
                _delay_ms(20);
      //TODO:: Please write your application code
    }
        return (0);
}
页: [1]
查看完整版本: MEGA16与TLC2543的SPI通信