
On va maintenant s’intéresser à l'interfaçage de la carte micro-contrôleur avec la raspberry pi.
Activation et vérification de l'I²C
Lors du démarrage de la raspberry pi, il est important que le driver I²C soit chargé
[ 15.669863] Freeing init memory: 132K [ 15.891808] EXT4-fs (mmcblk0p2): re-mounted. Opts: user_xattr,acl,barrier=1,data=ordered [ 16.350619] udevd[59]: starting version 182 [ 16.655836] bcm2708_i2c bcm2708_i2c.0: BSC0 Controller at 0x20205000 (irq 79) [ 16.748663] bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80) [ 16.816541] bcm2708_i2c bcm2708_i2c.1: BSC1 Controller at 0x20804000 (irq 79) [ 18.934210] smsc95xx 1-1.1:1.0: eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1 [ 22.859421] NET: Registered protocol family 10 [ 31.422506] Console: switching to colour dummy device 80x30 [ 31.536753] bcm2708_fb_check_var info(c78b5000) 720x480 (720x480), 691200, 16 [ 31.536774] bcm2708_fb_check_var var(c68ebdc8) 1x1 (1x1), 16, 345600 [ 31.536792] bcm2708_fb_set_par info(c78b5000) 1x1 (1x1), 691200, 16 [ 31.553110] BCM2708FB: start = c8826000,49385000 width=1, height=1, bpp=16, pitch=32 size=512 success=0 [ 32.899219] eth0: no IPv6 routers present
Il faut chargé le driver i2c-dev.ko pour créer les noeuds /dev/i2c-0 et /dev/i2c-1
# modprobe i2c-dev # lsmod Module Size Used by i2c_dev 4657 0 ipv6 237083 14 spidev 4274 0 spi_bcm2708 3969 0 i2c_bcm2708 3019 0
Pour vérifier si le microcontrôleur est bien connecté au bus I²C, on va utiliser l'utilitaire i2cdetect qui va nous donner tous les esclaves connectés à la raspberry pi.
# i2cdetect 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0.
I will probe address range 0x03-0x77.
Continue? [Y/n] Y
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
On remarque que l'esclave avec l'adresse 0x76 (le micro-contrôleur PIC16F876A) est bien vu par la raspberry pi.
Programme de test
Voici un petit programme de test sur la raspberry pi pour valider la communication I²C, elle permet d'afficher l'heure et la date du système :
Le fichier source :
/**
* Objet :
* --------------------------------------------------------------------------------
* Fichier : test_raspberry_lcd.c
* --------------------------------------------------------------------------------
* Version : 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
/***********************************/
/* Includes des fichiers du projet */
/***********************************/
/**********************************/
/* Constantes internes au fichier */
/**********************************/
#define syslog_info(format, ...) syslog(LOG_INFO, format, ##__VA_ARGS__)
#define syslog_debug(format, ...) syslog(LOG_DEBUG, format, ##__VA_ARGS__)
#define syslog_err(format, ...) syslog(LOG_ERR, format, ##__VA_ARGS__)
#define syslog_warning(format, ...) syslog(LOG_WARNING, format, ##__VA_ARGS__)
/**********************************/
/* Structures internes au fichier */
/**********************************/
typedef char char_t;
typedef float float32_t;
typedef double float64_t;
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
int32_t main(int32_t __attribute__((unused)) argc,
char_t __attribute__((unused)) *argv[]) {
int32_t i32_ret = -1;
int32_t i32_fd_i2c = -1;
char_t pi8_buf[16];
int i32_adapter_nr = 0; /* probably dynamically determined */
int i32_addr = 0x76; /* The I2C address */
char_t sz_filename[20];
// initialise buffer
memset(pi8_buf, 0, sizeof(pi8_buf));
memset(sz_filename, 0, sizeof(sz_filename));
sprintf(sz_filename, "/dev/i2c-%d", i32_adapter_nr);
// openlog is not necessary
syslog_info("[TEST_RASPBERRY_I2C] Start process ...");
// Open i2c dev node
i32_fd_i2c = open(sz_filename, O_RDWR);
if(i32_fd_i2c == -1) {
syslog_err("[TEST_RASPBERRY_I2C] open : %m");
return -1;
}
/* else nothing to do */
i32_ret = ioctl(i32_fd_i2c, I2C_SLAVE, i32_addr);
if (i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] ioctl : %m");
return -1;
}
/* else nothing to do */
// Clear display
pi8_buf[0] = 0x01;
pi8_buf[1] = 0x02;
// write I²C frame
i32_ret = write(i32_fd_i2c, pi8_buf, 2);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] write : %m");
close(i32_fd_i2c);
return -1;
}
/* else nothing to do */
sleep(1);
while(1) {
memset(pi8_buf, 0, sizeof(pi8_buf));
// Return Home
pi8_buf[0] = 0x02;
pi8_buf[1] = 0x02;
// write I²C frame
i32_ret = write(i32_fd_i2c, pi8_buf, pi8_buf[1]);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] write : %m");
close(i32_fd_i2c);
return -1;
}
/* else nothing to do */
usleep(50000);
st_time = time(NULL);
pst_dateheure = localtime(&st_time);
memset(pi8_buf, 0, sizeof(pi8_buf));
pi8_line1_ptr = &pi8_buf[0];
// String hour
*pi8_line1_ptr = 0x05;
pi8_line1_ptr ++;
*pi8_line1_ptr = 14;
pi8_line1_ptr ++;
sprintf(pi8_line1_ptr, " %02d:%02d:%02d", pst_dateheure->tm_hour, pst_dateheure->tm_min, pst_dateheure->tm_sec);
// write I²C frame
i32_ret = write(i32_fd_i2c, pi8_buf, pi8_buf[1]);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] write : %m");
close(i32_fd_i2c);
return -1;
}
/* else nothing to do */
usleep(100000);
memset(pi8_buf, 0, sizeof(pi8_buf));
// go to line 2, column 1
pi8_buf[0] = 0x03;
pi8_buf[1] = 0x04;
pi8_buf[2] = 2;
pi8_buf[3] = 1;
// write I²C frame
i32_ret = write(i32_fd_i2c, pi8_buf, pi8_buf[1]);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] write : %m");
close(i32_fd_i2c);
return -1;
}
/* else nothing to do */
usleep(50000);
memset(pi8_buf, 0, sizeof(pi8_buf));
pi8_line1_ptr = &pi8_buf[0];
// String date
*pi8_line1_ptr = 0x05;
pi8_line1_ptr ++;
*pi8_line1_ptr = 15;
pi8_line1_ptr ++;
sprintf(pi8_line1_ptr, " %02d/%02d/%04d", pst_dateheure->tm_mday, (pst_dateheure->tm_mon + 1), (pst_dateheure->tm_year + 1900));
// write I²C frame
i32_ret = write(i32_fd_i2c, pi8_buf, pi8_buf[1]);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] write : %m");
close(i32_fd_i2c);
return -1;
}
/* else nothing to do */
usleep(50000);
}
// Close i2c dev node
i32_ret = close(i32_fd_i2c);
if(i32_ret == -1) {
syslog_err("[TEST_RASPBERRY_I2C] close : %m");
return -1;
}
/* else nothing to do */
return 0;
}
Et le makefile :
CC = arm-unknown-linux-gnueabi-gcc
CFLAGS = -I../buildroot_test_a_del/output/host/usr/arm-unknown-linux-gnueabi/sysroot/usr/include -W -Wall
LDFLAGS = -L../buildroot_test_a_del/output/host/usr/arm-unknown-linux-gnueabi/sysroot/usr/lib -pthread -lrt
EXEC = test_raspberry_lcd
OBJS = test_raspberry_lcd.o
all: $(EXEC)
$(EXEC):$(OBJS)
@$(CC) -o $(EXEC) $^ $(LDFLAGS)
%.o:%.c
@echo [CC] $^
@$(CC) -o $@ -c $^ $(CFLAGS)
clean:
@echo [CLEAN]
@rm *.o $(EXEC) -f
On lance la compilation du programme de test avec la commande make et on vérifie que l’exécutable est bien compilé pour notre cible (raspberry pi).
# file test_raspberry_lcd test_raspberry_lcd: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.25, not stripped
On lance l’exécutable de test avec la commande :
# ./test_raspberry_lcd
Résultat
Quelques photos
Lien vers la première partie du tutoriel : Afficheur alphanumérique (Partie 1)
Lien vers la deuxième partie du tutoriel : Afficheur alphanumérique (Partie 2)







Aucun commentaire:
Enregistrer un commentaire