zoukankan      html  css  js  c++  java
  • 树莓派与arduino通过spi通信

    逻辑电平转换

    树莓派的逻辑电平为3.3v,Arduino为5v,需要进行逻辑转换,在某宝买了个逻辑转换器:

    HV接5V电源

    LV接3.3V电源

    GND接电源负极,两个电源公地

    RXI输入5v TTL,将在RXO输出3.3v TTL

    TXI输入输出3.3V TTL  ,TXO输入输出5V TTL,  TXI与TXO双向互转

     

    连线方式

    树莓派的程序

      1 /*
      2  * SPI testing utility (using spidev driver)
      3  *
      4  * Copyright (c) 2007  MontaVista Software, Inc.
      5  * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License as published by
      9  * the Free Software Foundation; either version 2 of the License.
     10  *
     11  * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
     12  */
     13 
     14 #include <stdint.h>
     15 #include <unistd.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <getopt.h>
     19 #include <fcntl.h>
     20 #include <sys/ioctl.h>
     21 #include <linux/types.h>
     22 #include <linux/spi/spidev.h>
     23 
     24 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
     25 
     26 static void pabort(const char *s)
     27 {
     28     perror(s);
     29     abort();
     30 }
     31 
     32 static const char *device = "/dev/spidev0.0";
     33 static uint8_t mode;
     34 static uint8_t bits = 8;
     35 static uint32_t speed = 500000;
     36 static uint16_t delay;
     37 
     38 static void transfer(int fd)
     39 {
     40     int ret;
     41     uint8_t tx[] = {
     42         0x48, 0x45, 0x4C, 0x4C, 0x4F,
     43         0x20, 
     44         0x57, 0x4F, 0x52, 0x4C, 0x44,
     45         0x0A 
     46     };
     47     uint8_t rx[ARRAY_SIZE(tx)] = {0, };
     48     struct spi_ioc_transfer tr = {
     49         .tx_buf = (unsigned long)tx,
     50         .rx_buf = (unsigned long)rx,
     51         .len = ARRAY_SIZE(tx),
     52         .delay_usecs = delay,
     53         .speed_hz = speed,
     54         .bits_per_word = bits,
     55     };
     56 
     57     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
     58     if (ret < 1)
     59         pabort("can't send spi message");
     60 
     61     /*
     62     for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
     63         if (!(ret % 6))
     64             puts("");
     65         printf("%.2X ", rx[ret]);
     66     }
     67     puts("");
     68     */
     69 }
     70 
     71 static void print_usage(const char *prog)
     72 {
     73     printf("Usage: %s [-DsbdlHOLC3]
    ", prog);
     74     puts("  -D --device   device to use (default /dev/spidev1.1)
    "
     75          "  -s --speed    max speed (Hz)
    "
     76          "  -d --delay    delay (usec)
    "
     77          "  -b --bpw      bits per word 
    "
     78          "  -l --loop     loopback
    "
     79          "  -H --cpha     clock phase
    "
     80          "  -O --cpol     clock polarity
    "
     81          "  -L --lsb      least significant bit first
    "
     82          "  -C --cs-high  chip select active high
    "
     83          "  -3 --3wire    SI/SO signals shared
    ");
     84     exit(1);
     85 }
     86 
     87 static void parse_opts(int argc, char *argv[])
     88 {
     89     while (1) {
     90         static const struct option lopts[] = {
     91             { "device",  1, 0, 'D' },
     92             { "speed",   1, 0, 's' },
     93             { "delay",   1, 0, 'd' },
     94             { "bpw",     1, 0, 'b' },
     95             { "loop",    0, 0, 'l' },
     96             { "cpha",    0, 0, 'H' },
     97             { "cpol",    0, 0, 'O' },
     98             { "lsb",     0, 0, 'L' },
     99             { "cs-high", 0, 0, 'C' },
    100             { "3wire",   0, 0, '3' },
    101             { "no-cs",   0, 0, 'N' },
    102             { "ready",   0, 0, 'R' },
    103             { NULL, 0, 0, 0 },
    104         };
    105         int c;
    106 
    107         c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
    108 
    109         if (c == -1)
    110             break;
    111 
    112         switch (c) {
    113         case 'D':
    114             device = optarg;
    115             break;
    116         case 's':
    117             speed = atoi(optarg);
    118             break;
    119         case 'd':
    120             delay = atoi(optarg);
    121             break;
    122         case 'b':
    123             bits = atoi(optarg);
    124             break;
    125         case 'l':
    126             mode |= SPI_LOOP;
    127             break;
    128         case 'H':
    129             mode |= SPI_CPHA;
    130             break;
    131         case 'O':
    132             mode |= SPI_CPOL;
    133             break;
    134         case 'L':
    135             mode |= SPI_LSB_FIRST;
    136             break;
    137         case 'C':
    138             mode |= SPI_CS_HIGH;
    139             break;
    140         case '3':
    141             mode |= SPI_3WIRE;
    142             break;
    143         case 'N':
    144             mode |= SPI_NO_CS;
    145             break;
    146         case 'R':
    147             mode |= SPI_READY;
    148             break;
    149         default:
    150             print_usage(argv[0]);
    151             break;
    152         }
    153     }
    154 }
    155 
    156 int main(int argc, char *argv[])
    157 {
    158     int ret = 0;
    159     int fd;
    160 
    161     parse_opts(argc, argv);
    162 
    163     fd = open(device, O_RDWR);
    164     if (fd < 0)
    165         pabort("can't open device");
    166 
    167     /*
    168      * spi mode
    169      */
    170     ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
    171     if (ret == -1)
    172         pabort("can't set spi mode");
    173 
    174     ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
    175     if (ret == -1)
    176         pabort("can't get spi mode");
    177 
    178     /*
    179      * bits per word
    180      */
    181     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    182     if (ret == -1)
    183         pabort("can't set bits per word");
    184 
    185     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    186     if (ret == -1)
    187         pabort("can't get bits per word");
    188 
    189     /*
    190      * max speed hz
    191      */
    192     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    193     if (ret == -1)
    194         pabort("can't set max speed hz");
    195 
    196     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
    197     if (ret == -1)
    198         pabort("can't get max speed hz");
    199 
    200     printf("spi mode: %d
    ", mode);
    201     printf("bits per word: %d
    ", bits);
    202     printf("max speed: %d Hz (%d KHz)
    ", speed, speed/1000);
    203 
    204     transfer(fd);
    205 
    206     close(fd);
    207 
    208     return ret;
    209 }

    Arduino的程序

     1 // Written by Nick Gammon
     2 // February 2011
     3 
     4 
     5 #include <SPI.h>
     6 
     7 char buf [100];
     8 volatile byte pos;
     9 volatile boolean process_it;
    10 
    11 void setup (void)
    12 {
    13   Serial.begin (115200);   // debugging
    14 
    15   // have to send on master in, *slave out*
    16   pinMode(MISO, OUTPUT);
    17   
    18   // turn on SPI in slave mode
    19   SPCR |= _BV(SPE);
    20   
    21   // get ready for an interrupt 
    22   pos = 0;   // buffer empty
    23   process_it = false;
    24 
    25   // now turn on interrupts
    26   SPI.attachInterrupt();
    27 
    28 }  // end of setup
    29 
    30 
    31 // SPI interrupt routine
    32 ISR (SPI_STC_vect)
    33 {
    34 byte c = SPDR;  // grab byte from SPI Data Register
    35   
    36   // add to buffer if room
    37   if (pos < sizeof buf)
    38     {
    39     buf [pos++] = c;
    40     
    41     // example: newline means time to process buffer
    42     if (c == '
    ')
    43       process_it = true;
    44       
    45     }  // end of room available
    46 }  // end of interrupt routine SPI_STC_vect
    47 
    48 // main loop - wait for flag set in interrupt routine
    49 void loop (void)
    50 {
    51   if (process_it)
    52     {
    53     buf [pos] = 0;  
    54     Serial.println (buf);
    55     pos = 0;
    56     process_it = false;
    57     }  // end of flag set
    58     
    59 }  // end of loopang
  • 相关阅读:
    multiprocessing.Pool报pickling error
    Python 数据库的Connection、Cursor两大对象
    python中的tcp示例详解
    Python网络编程篇之select和epoll
    python select epoll poll的解析
    python网络编程——IO多路复用之epoll
    python实现并发服务器实现方式(多线程/多进程/select/epoll)
    python select模块
    CRM客户关系管理系统(七)
    CRM客户关系管理系统(六)
  • 原文地址:https://www.cnblogs.com/brep/p/4238731.html
Copyright © 2011-2022 走看看