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无输出