wiringPi spi

本文地址:http://tongxinmao.com/Article/Detail/id/39

#include <wiringPi.h> 

#include <stdio.h>


//LINUX:  gcc spi.c -lwiringPi -lrt



/*

中断采集并口数据,超过一段时间无数据后认为发送完毕,将数据保存为打印文件然后转换为位图文件

调度程序发现位图文件后进行OCR或字符识别出金额

图形界面生成二维码信息并声光提示

本地保存并上传金额到服务器




*/



/*

1.SPI 的模式为MODE0 即 CPOL = 0;CPHA = 0; 。数据位为16bit

2.在第一次初始化并口时,需要对FPGA_RESET 拉低进行初始化!低电平时间为100ms,正常工作时,FPGA_RESET 为高电平。

如果一直保持FPGA_RESET为低电平,电脑可以正常发送数据到打印机,但是FPGA不能获取到打印数据。

(相当于树莓派主板没有正常启动或者关电的情况下,可以正常打印的功能。)


3.当并口收到数据时,FPGA_INT1会有一个高电平脉冲,当树莓派检测到该脉冲时,需要先FPGA_CS拉低进行选择,

然后发送读取数据指令0x40,紧跟一个任意到数据以产生8个clk使FPGA把收到的数据发送到SPI上。


我提供的STM32F4的DEMO可以参考。

*/

#define GPIO_PIN_CS 21 // 21GPIO5  11ce1

#define GPIO_PIN_RST 22

#define GPIO_PIN_ISR1 3

#define GPIO_PIN_ISR2 2

#define GPIO_PIN_BUSY 23

#define GPIO_PIN_WR 24


#define GPIO_PIN_LED1 27

#define GPIO_PIN_LED2 29

#define GPIO_PIN_SPK 4

#define SPI1 1


#define GPIO_PIN_TESTLED 1



typedef unsigned char u8;

typedef unsigned short u16;


#include <stdio.h>

#include <time.h>

#include <stdlib.h>

#include <signal.h>

#include <string.h>

#include <unistd.h>


#define CLOCKID CLOCK_REALTIME


void spi_read_byte(u8 addr, u8 *data);


void sig_handler(int signo)

{

printf("timer_signal function! %d\n", signo);

}


int timer(int ms,int forever)

{

// XXX int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

// signum--指定的信号编号,可以指定SIGKILL和SIGSTOP以外的所有信号编号

// act结构体--设置信号编号为signum的处理方式

// oldact结构体--保存上次的处理方式

//

// struct sigaction 

// {

// void (*sa_handler)(int); //信号响应函数地址

// void (*sa_sigaction)(int, siginfo_t *, void *);   //但sa_flags为SA——SIGINFO时才使用

// sigset_t sa_mask;         //说明一个信号集在调用捕捉函数之前,会加入进程的屏蔽中,当捕捉函数返回时,还原

// int sa_flags;

// void (*sa_restorer)(void); //未用

// };

//

timer_t timerid;

struct sigevent evp;


struct sigaction act;

memset(&act, 0, sizeof(act));

act.sa_handler = sig_handler;

act.sa_flags = 0;


// XXX int sigaddset(sigset_t *set, int signum);  //将signum指定的信号加入set信号集

// XXX int sigemptyset(sigset_t *set); //初始化信号集

sigemptyset(&act.sa_mask);


if (sigaction(SIGUSR1, &act, NULL) == -1)

{

perror("fail to sigaction");

exit(-1);

}


memset(&evp, 0, sizeof(struct sigevent));

evp.sigev_signo = SIGUSR1;

evp.sigev_notify = SIGEV_SIGNAL;

if (timer_create(CLOCK_REALTIME, &evp, &timerid) == -1)

{

perror("fail to timer_create");

exit(-1);

}


struct itimerspec it;

//第一次间隔it.it_value这么长,以后每次都是it.it_interval这么长,就是说it.it_value变0的时候会装载it.it_interval的值  

if(forever){

it.it_interval.tv_sec = ms/1000;

it.it_interval.tv_nsec = ms%1000*1000000;

}

else{

   it.it_interval.tv_sec =0;

it.it_interval.tv_nsec = 0;

}


it.it_value.tv_sec =ms/1000;

it.it_value.tv_nsec = ms%1000*1000000;

// XXX int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value,struct itimerspec *old_value);  

    // timerid--定时器标识  

    // flags--0表示相对时间,1表示绝对时间  

    // new_value--定时器的新初始值和间隔,如下面的it  

    // old_value--取值通常为0,即第四个参数常为NULL,若不为NULL,则返回定时器的前一个值

    

if (timer_settime(timerid, 0, &it, 0) == -1)

{

perror("fail to timer_settime");

exit(-1);

}


 


return 0;

}

 

 

 void LPTIsr(void)

{

    u8 b;

    printf("LPT ISR %02X",b);

    spi_read_byte(0,&b);

    printf("LPT ISR %02X",b);

 

}


 

void LPTCS(char level)

{

    digitalWrite(GPIO_PIN_CS, level) ;

}

void LPTReset(void)

{

     

    digitalWrite(GPIO_PIN_RST, LOW) ;

delay(120);//去抖动 

digitalWrite(GPIO_PIN_RST, HIGH) ;

}


 

void LPTInit(){

    wiringPiSetup() ;

    pinMode (GPIO_PIN_CS, OUTPUT) ;

    pinMode (GPIO_PIN_RST, OUTPUT) ;

    pinMode (GPIO_PIN_BUSY, OUTPUT) ;

    pinMode (GPIO_PIN_WR, OUTPUT) ;


pinMode (GPIO_PIN_LED1, OUTPUT) ;

pinMode (GPIO_PIN_LED2, OUTPUT) ;

pinMode (GPIO_PIN_TESTLED, OUTPUT) ;

pinMode (GPIO_PIN_SPK, OUTPUT) ;

pinMode (GPIO_PIN_ISR1, INPUT) ;

    pinMode (GPIO_PIN_ISR2, INPUT) ;

   pullUpDnControl(GPIO_PIN_ISR1,PUD_UP);

pullUpDnControl(GPIO_PIN_ISR2,PUD_UP);

LPTReset();

if (wiringPiSPISetup(1, 500000) == -1) 

    {

        printf("wiringPiSPISetup fail");

        

    }

    

     if(wiringPiISR(GPIO_PIN_ISR1, INT_EDGE_BOTH, LPTIsr)){

    fprintf (stderr, "Unable to setup ISR: %s\n") ;

    return   ;

  }

  

    

    wiringPiISR (GPIO_PIN_ISR2, INT_EDGE_BOTH,  LPTIsr) ;

    printf("INIT OK\n");

    

    

}


 void spi_read_byte(u8 addr, u8 *data)

{

unsigned short data16 = 0;

u8 cmd[2]  = {0,0x40};

cmd[1]|=addr;

LPTCS(LOW);


//READ

wiringPiSPIDataRW(SPI1, cmd, 2);

 

*data = cmd[1];

LPTCS(HIGH);


}


static void spi_write_byte(u8 addr, u8 data)

{


u8 cmd[2]={0,0x60};

LPTCS(LOW);

cmd[1]|=addr;

cmd[0]=data;

    wiringPiSPIDataRW(SPI1, cmd, 2);  

LPTCS(HIGH);


}


int main(void)

{

   

    

  //  timer(1000,0);

    

   

    u8 led=0;

    u8 cmd[]={0X23,0X34};

    LPTInit();

    printf("LOOP ");

    

    while(1){

        u8 b;

        

        

      // delay(100);

        digitalWrite(GPIO_PIN_TESTLED, led);

        led=!led;

        delay(10);

       // printf("LOOP ");

         

      

         

    }

}


int maintest (void)

{

    int i=0;

    if (wiringPiSPISetup(1, 500000) == -1) 

    {

        printf("wiringPiSPISetup fail");

       return -1;

    }

   

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

    {

        char c = i;

        printf("w:%x \n",c);

        

        wiringPiSPIDataRW(1, &c, 1);

        printf("r:%x \n",c);

        delay(1000);

    }

}


上一篇:树莓派安装配置启动CHROME及FLASH支持
下一篇:printf无输出