天天看點

基于GCCAVR的TLC2543讀寫程式----模拟SPI方式實作

TLC2453的操作也比較簡單,通過模拟的方式實作隻需要看一下時序圖把時序搞對即可。

在硬體SPI中,讀和寫實可以通過硬體同步進行的,是以在寫入本次指令字時可以同時讀取上一次指令的資料,在模拟SPI的方式中,讀和寫無法同步進行,是以隻能先寫後讀,讀取的即為本次指令的資料。

本程式在測試過程中發現寫入指令0x04時讀取的資料是正确的,而按照datasheet說明,如果以12位資料方式輸出的話低四位應該為1000或者0000,具體原因尚未搞清楚,但是本程式測試是正确的。

程式如下:

hal.h

/**************************(C) COPYRIGHT emouse 2011*************************** 

名稱:hal.h 

功能:TLC2543測試程式 

作者:emouse 

時間:2011.1.11 

版本:1.0 

注意:無 

*******************************************************************************/  

#include"avr/io.h"   

#include"avr/interrupt.h"   

#include"util/delay.h"  

#define SetBit(Port,N)  (Port|=(1<<N))    //設定IO某一位   

#define ClrBit(Port,N)  (Port&=~(1<<N))   //清空IO某一位   

#define ReverBit(Port,N)  (Port^=(1<<N))   //取反IO某一位   

#define GetBit(Pin,N)   ((Pin>>N)&0x01)   //讀取IO某一位  

/******************************************************************************* 

名稱:void USART0_Init(void)  

功能:序列槽0初始化 

參數:無 

void USART0_Init(void)   

{   

UCSR0A=0x20; //波特率不加倍,單機通信模式   

UCSR0B=0x18; //中斷不使能,允許發送和接收   

UCSR0C=0x06;//異步模式,無校驗,8位資料,1位停止位   

UBRR0H=0x00;   

UBRR0L=51;//9600波特率   晶振8M  

}   

名稱:void USART0_Putc(unsigned char c) 

功能:發送一個字元 

參數:unsigned char c 

void USART0_Putc(unsigned char c)  

{  

    while(!(UCSR0A&(1<<UDRE0)));  //等待發送緩沖空   

    UDR0=c;    //發送資料   

}  

名稱:void USART0_Puts(unsigned char * str) 

功能:發送字元串 

參數:unsigned char * str 待發送的字元串 

void USART0_Puts(unsigned char * str)  

    while(*str)  

    {  

        USART0_Putc(*str++);  

    }  

/***************模拟SPI的相關宏定義********************/  

#define TLC2543_Port PORTC      //設定使用的端口  

#define TLC2543_DDR DDRC  

#define TLC2543_PIN PINC  

#define TLC2543_CS 0            //設定每個信号對應的引腳  

#define TLC2543_MISO 1  

#define TLC2543_MOSI 2  

#define TLC2543_CLK 3  

#define TLC2543_CS_H (TLC2543_Port|=(1<<TLC2543_CS))  

#define TLC2543_CS_L (TLC2543_Port&=~(1<<TLC2543_CS))  

#define TLC2543_GetMISO ((TLC2543_PIN>>TLC2543_MISO)&0x01)  

#define TLC2543_MOSI_H (TLC2543_Port|=(1<<TLC2543_MOSI))  

#define TLC2543_MOSI_L (TLC2543_Port&=~(1<<TLC2543_MOSI))  

#define TLC2543_CLK_H (TLC2543_Port|=(1<<TLC2543_CLK))  

#define TLC2543_CLK_L (TLC2543_Port&=~(1<<TLC2543_CLK))  

unsigned char spi_delay;    //設定信号的持續時間,相當于設定SPI的速度  

名稱:void TLC2543_Init() 

功能:模拟SPI時序的端口初始化工作 

void TLC2543_Init()  

    TLC2543_Port|=((1<<TLC2543_CS)|(1<<TLC2543_MISO)|(1<<TLC2543_MOSI)|(1<<TLC2543_CLK));  

    TLC2543_DDR|=(((1<<TLC2543_CS)|(1<<TLC2543_MOSI)|(1<<TLC2543_CLK))&(~(1<<TLC2543_MISO)));  

    TLC2543_CS_H;  

    TLC2543_CLK_L;  

    spi_delay=20;  

名稱:TLC2543_Send(unsigned char data) 

功能:發送SPI資料 

參數:unsigned char data 

void TLC2543_Send(unsigned char data)  

    unsigned char i;  

    TLC2543_CS_L;       //拉低片選信号  

    TLC2543_CLK_L;      //時鐘空閑時為低電平   

    TLC2543_MOSI_L;  

    _delay_us(spi_delay);  

    for(i=0;i<8;i++)  

        if(data&(0x80>>i))//高位在前,低位在前改為(0x01<<i)  

            TLC2543_MOSI_H;  

        else  

            TLC2543_MOSI_L;  

        _delay_us(spi_delay);  

        TLC2543_CLK_H;      //在上升沿更新資料  

        TLC2543_CLK_L;  

    TLC2543_CS_H;       //拉高片選,完成一次資料傳輸  

名稱:unsigned char TLC2543_Get()  

功能:接收SPI資料 

參數:傳回data 

unsigned int TLC2543_Get()   

    unsigned int data=0x000;  

    for(i=0;i<12;i++)//讀取12位ad值  

        if(TLC2543_GetMISO)  

            data|=(0x800>>i);  

    return data;  

名稱:unsigned int Read_TLC2543(unsigned char chan) 

功能:讀取標明通道上的AD值 

參數:輸入參數為需要讀取的通道,傳回為AD值 

時間:2011.1.12 

注意:在硬體SPI中,讀和寫實可以通過硬體同步進行的,是以在寫入本次指令字時可以同時 

      讀取上一次指令的資料,在模拟SPI的方式中,讀和寫無法同步進行,是以隻能先寫後 

      讀,讀取的即為本次指令的資料。 

unsigned int Read_TLC2543(unsigned char chan)  

    unsigned int adc_data;  

    chan <<= 4;  

    chan |= 0x04;  

    //按照datasheet這裡發送的資料低四位應該為0才是以12位資料方式輸出,但是測試發現這樣發送讀取資料是對的  

    TLC2543_Send(chan);  

    adc_data = TLC2543_Get();  

    return adc_data;  

主程式中利用序列槽讀取轉換數值進行測試

#include"hal.h"  

#include"stdlib.h"  

unsigned int data;  

unsigned char *s="00000";  

int main(void)   

{      

    USART0_Init();  //初始化USART0接口     

    DDRA=0XFF;  

    PORTA=0XFF;   

    TLC2543_Init();  

    USART0_Puts("SPI test");  

    while(1)   

    {        

        data=Read_TLC2543(0);  

        //USART0_Putc(data);  

        ReverBit(PORTA,0);  

        USART0_Puts(utoa(data,s,10));//轉換成字元串輸出友善調試。  

        USART0_Puts("/t");  

        data=Read_TLC2543(1);  

        USART0_Puts(utoa(data,s,10));  

        USART0_Puts("/n");  

        _delay_ms(50);        

    }   

 本文轉自emouse部落格園部落格,原文連結:http://www.cnblogs.com/emouse/archive/2011/01/12/2198185.html,如需轉載請自行聯系原作者

繼續閱讀