Home › Forum › Microcontrôleurs & microprocesseurs › 18F24K22 et SPI

Forum

Veuillez vous identifier avant de répondre ou pour vous abonner à cette discussion

Sujet: 18F24K22 et SPI

Auteur Message

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 24-05-2011 20:42

Bonjour

pour une appli, j'ai besoin d'un PIC avec deux ports serie. Je travaille avec un PIC18F24K22
L'appli demande de 8 à 16k de ram. Le PIC est donc épaulé d'une 23K256: 32ko via SPI.
Elle est donnée pour 2.7 --> 3.6V. Valeur limite 4.5V
Comme par ailleurs je n'arrive pas à faire fonctionner le PIC à 3.3V (mon ICD3 ne le detecte pas à cette tension ...), j'ai alimenté le montage sous 4V. Le PIC fonctionne, la RAM est sous la spec limite... Théoriquement, ça doit le faire. Le PIC tourne à 20Mhz sur quartz externe.
J'utilise le port SPI1 du PIC. Le CS est réalisé via RC2.
Apres un bon epluchage de doc, je pense la config SPI du PIC correcte.
J'ai fais un bout de code d'essais. Pour l'heure, en balayant la RAM, je trouve toujours la meme sequence de valeur, mais uniquement des 0x00 et 0xFF.
Les ecritures dans la RAM ou dans l'octet de config du mode ne donnent.... rien.
Le code est le suivant:

#include ;
#include "delay.h";

// 23K256
#define SPI_WRITE 0x02
#define SPI_READ 0x03
#define SPI_RDSR 0x05
#define SPI_WRSR 0x01

void SPI_Write(unsigned int addr,unsigned char data)
{
// Activate the SS SPI Select pin
PORTCbits.RC2 = 0;
SSPBUF = SPI_WRITE;
while(!SSP1STATbits.BF);
SSPBUF = addr >> 8;
while(!SSP1STATbits.BF);
SSPBUF = addr & 0xFF;
while(!SSP1STATbits.BF);
SSPBUF = data;
while(!SSP1STATbits.BF);
PORTCbits.RC2 = 1;
}
unsigned char SPI_Read(unsigned int addr)
{
// Activate the SS SPI Select pin
PORTCbits.RC2 = 0;
SSPBUF = SPI_READ;
while(!SSP1STATbits.BF);
SSPBUF = addr >> 8;
while(!SSP1STATbits.BF);
SSPBUF = addr & 0xFF;
while(!SSP1STATbits.BF);
// Send Dummy transmission for reading the data
SSPBUF = 0x00;
while(!SSP1STATbits.BF);
PORTCbits.RC2 = 1;
return(SSPBUF);
}

void SPI_Write_SR(unsigned char data)
{
// Activate the SS SPI Select pin
PORTCbits.RC2 = 0;
SSPBUF = SPI_WRSR;
while(!SSP1STATbits.BF);
SSPBUF = data;
while(!SSP1STATbits.BF);
PORTCbits.RC2 = 1;
}

unsigned char SPI_Read_SR(void)
{
// Activate the SS SPI Select pin
PORTCbits.RC2 = 0;
SSPBUF = SPI_RDSR;
while(!SSP1STATbits.BF);
// Send Dummy transmission for reading the data
SSPBUF = 0x00;
while(!SSP1STATbits.BF);
PORTCbits.RC2 = 1;
return(SSPBUF);
}

void main()
{
unsigned int i, k;
char ch;
unsigned char c;
unsigned int Shift;

PORTA = 0;
PORTB = 0;
PORTC = 0;

TRISA = 0x00;
TRISB = 0x80;
TRISC = 0x90;
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;


// All irq disabled
PIE1=0;
PIE2=0;


// SPI cfg
SSPSTAT = 0x40; // Set SMP=0 and CKE=1. Notes: The lower 6 bit is read only
SSP1STATbits.SMP=0; // OK
SSP1STATbits.CKE=1; // OK
SSPCON1 = 0x21; // Enable SPI Master with Fosc/4 --> 1/16
SSP1CON1bits.CKP =0; // OK
PORTCbits.RC2 = 0; // Disable Chip Select


i=0;
Shift=0;
RB6=0;
while (1)
{
LcdGoto(0);
c = SPI_Read_SR();
LcdPutHex(c);

for (k=0; k Disp

RB6=!RB6; // I'm alive

// ---> Disp counter : i
i++;
if (!(i%10))
Shift++;

if (!(i%50))
{
for (k=0; k<8; k++)
{
SPI_Write(k+Shift,k%256);
}
}
DelayMs(100);
}
}


La, je suis planté depuis une semaine. Snif. Rien à l'horizon. Si quelqu'un peut apporter de l'eau à mon moulin....

obdh

229 messages

Habitué
Habitué

Read post 24-05-2011 20:53

C'est le genre de truc qu'il faut valider pas à pas (au moins dès qu'il y a un doute), en commençant par le matériel, donc avec un analyseur logique ou un oscilloscope numérique, branché sur le spi. Il suffit qu'un IO soit mal configuré pour qu'il ne sorte rien. Quand on met en évidence un problème dans les signaux, on peut déjà chercher un moment une erreur dans le code, alors là, en n'ayant que le code et sans savoir à quoi ressemblent les signaux... Ca peut être aussi un non respect du protocole de communication de la mémoire.

RISC

54 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 25-05-2011 21:46

Salut Petard,

A te lire je sens que tu as des problèmes hardware...
L'ICD3 fonctionne à partir de 1.8V ou 2V (à vérifier exactement).

Peux-tu faire voir ton schéma ?
Comment est faite ton alimentation ?
Si tu fonctionnes en 4V TU DETRUIS TA RAM !!!!

Ou sont les bits de configuration dans ton programme...

Il existe des exemples de code pour les périphériques des PIC18 ici : http://www.microchip.com/codeexamples

a+

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 26-05-2011 09:29

L'analyseur, si j'en avais un, c'est sur, ca irait plus vite. Mais ce n'est pas le cas Apres une etude consolidée des docs de chaque partie, la config SPI du PIC semble ad-hoc.
L'ICD3 est en effet en mesure des descendre, a minima, à 3.3V. Mais dès que l'alimentation de la carte descend sous 4V, il declare que l'ID du PIC n'est pas bonne. A premiere vue, je ne vois pas ce qui peut clocher. Faute d'information pour aller plus loin, je tente le contournement.
La RAM est en effet donnée pour une alimentation jusqu'à 3.6V (de memoire, sans jeu de mot). Mais il est egalement indiqué de maniere assez vague un Vmax de 4.5V. Ca vaut la peine d'essayer. Alimentation reduite à 4.7V. Ajout d'une 4007 et voila une alimentation (basique) de 4V. Le PIC tourne parfaitement. La RAM est à ce menu depuis 15 jours. Force est de reconnaitre qu'elle est encore vivante. Voir ci-dessous. Cette config permet de faire le defrichage soft. La version finale prendra soin des specifications de chacun.
Le système est on ne peut plus simple. 1 PIC, 1 Ram et un quartz. Cablage de la ram sur le SPI1 du PIC:
- SCK sur 14 du PIC, sur 6 de la RAM
- SDI sur 15 du PIC, sur 2 de la RAM
- SDO sur 16 du PIC, sur 5 de la RAM
- CS\ via RC2 soit 13 du PIC, sur 1 de la RAM
- HOLD\ de la RAM forcée à Vcc
Oscillateur HS du PIC à 20Mhz
Hier, j'ai retravaillé le code. J'ai pu me rendre compte que lorsque les lectures/ecritures se faisaient dans le main et non pas dans des fonctions, cela donnait un resultat infiniment plus stables et prédictifs. Une heure plus tard, ca tournait de maniere parfaite. Les seules modifications sont au niveau des fonctions de lecture / ecriture de la RAM.
Elles sont à présent:

void SPI_Write(unsigned int addr,unsigned char data)
{
PORTCbits.RC2 = 0;
SSP1BUF = SPI_WRITE;
while(!SSP1STATbits.BF);
SSP1BUF = addr >> 8;
while(!SSP1STATbits.BF);
SSP1BUF = addr & 0xFF;
while(!SSP1STATbits.BF);
_delay(50);
SSP1BUF = data;
while(!SSP1STATbits.BF);
_delay(50);
PORTCbits.RC2 = 1;
}

unsigned char SPI_Read(unsigned int addr)
{
PORTCbits.RC2 = 0;
SSP1BUF = SPI_READ;
while(!SSP1STATbits.BF);
SSP1BUF = addr >> 8;
while(!SSP1STATbits.BF);
SSP1BUF = addr & 0xFF;
while(!SSP1STATbits.BF);
_delay(100);
SSP1BUF = 0x00;
while(!SSP1STATbits.BF);
PORTCbits.RC2 = 1;
return(SSP1BUF);
}

La difference réside uniquement dans l'ajout des _delay().
Je suis depuis passé à la vitesse maxi du SPI, cela fonctionne parfaitement.
Nul mention de ces tempos dans la doc de la ram.
Si qqn à une idée la dessus, je suis preneur.

Modifié par petard le 26-05-2011 09:38

RISC

54 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 28-05-2011 12:17

Salut,

Au vu de tes dire, c'est sur que tu as un problème hardware.
Tous les comportements que tu mentionnes en sont les preuves.
Il faut commencer par solutionner cela avant d'utiliser les composants en dehors de leur spécifications (A NE JAMAIS FAIRE !!)

Peux-tu poster ou donner un lien vers ton schéma ?

a+

obdh

229 messages

Habitué
Habitué

Read post 28-05-2011 12:34

Cela peut venir aussi d'un temps minimal entre deux actions, lié par exemple à des vitesses de bus et de périphériques (internes au processeur) différentes. Les docs ne sont pas toujours clairs. Ne connaissant pas ce processeur, je ne suis sûr de rien. Mais dès que l'on fait du soft directement lié à du matériel, avoir un oscilloscope est un minimum, idéalement numérique pour pouvoir débugger des liaisons séries. Ou un oscilloscope analogique accompagné d'un analyseur logique. On peut avoir ce matériel à des prix très abordables, en neuf ou en occasion.

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 30-05-2011 21:59

Voici le montage. On est pas loin du minimalisme à présent (osc interne à 16MHz).
Je suis toujours avec les tempos, et cela tourne impek.
Sinon, j'ai tenté le coup à l'oscillo. Meme avec qqc de pas trop mauvais, le debugage SPI en analogique, c'est raide !-)

Modifié par petard le 30-05-2011 22:01

Daudet78.

113 messages

Visiteur régulier
Visiteur régulier

Read post 31-05-2011 03:44

Le câblage de ton LTC485 est assez curieux ..... la transmission par /RE DE ??????

- Il faut connecter TX du PIC sur la broche 4 DI
- Il faut connecter RX du PIC sur la broche 1 RO
- Il faut connecter une sortie du PIC sur les broches 2 /RE et 3 DE pour indiquer dans quel sens est le LTC485 (émission ou réception)

et mettre une 120 ohms entre le "A" et le "B" du premier ainsi que du dernier de ta ligne de transmission

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 31-05-2011 07:53

Le cablage du LTC peut paraitre curieux au premier abord. Si on y regarde de plus pres, il est pleinement fonctionnel (il faut secouer un peu la doc d'un driver RS485).
Objectif: réaliser la fonction Rx/Tx RS485 ... avec seulement deux pin du µC. Dans le cas présent, il n'est pas vraiment justifé. Mais chacun de mes montages utilise l'experience et les bibliothèques des précédants....
Le montage est raccordé à un bus de terrain. C'est la topologie de ce dernier qui dicte ou est placée la résistance de 120 ohms.

Daudet78.

113 messages

Visiteur régulier
Visiteur régulier

Read post 31-05-2011 09:54

petard Si on y regarde de plus pres, il est pleinement fonctionnel (il faut secouer un peu la doc d'un driver RS485).
Cela m'étonnerait beaucoup !
Ce montage, en émission, fait du
- Soit tension nulle (quand on veut transmettre un "0", le driver est en trois état)
- Soit tension (quand on veut transmettre un "1")

Alors que le fonctionnement normal, c'est une tension différentielle positive ou négative suivant le bit à transmettre.

Ce montage est tombé en marche .... et je le déconseille fortement !

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 31-05-2011 10:04

Le fonctionnement du montage est exactement celui que tu décris. Et il transmet les 0 et 1 comme requis pour du RS485.

Pour ce qui est de mon expérience personnelle, il est en production depuis plusieurs années. Et il "tombe en marche" à chaque fois. Jamais une defaillance.

Je l'avais mis en oeuvre la premiere fois dans une situation de nombre de pin "critique". Depuis, je l'ai croisé en reverse engineering à plusieurs reprises. Il a meme été mentionné dans Elektor il y a 2 ou 3 mois dans la série d'article "Le Bus Arrive".

Daudet78.

113 messages

Visiteur régulier
Visiteur régulier

Read post 31-05-2011 11:23

petard Et il transmet les 0 et 1 comme requis pour du RS485.
ce n'est pas vrai ! la norme RS485 (ou RS422) spécifie une inversion de polarité
Il a meme été mentionné dans Elektor il y a 2 ou 3 mois dans la série d'article "Le Bus Arrive".
Sorry, mais ce n'est pas une référence crédible ... si tu savais ce que l'on trouve comme erreur et comme mauvaise bidouille sur le WEB et la littérature ! Pour moi, sont crédibles les normes et les spécifications .

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 31-05-2011 13:34

Entre nous, je ne suis pas là pour me faire des noeuds avec la théorie, mais plutot pour m'amuser.
Le sujet d'origine etait le SPI. A présent tout fonctionne. La seule interrogation qui subsiste est la necessité des tempos. Sans elles, point de salut dans mon cas.
Elles ne sont pas évoquées dans la doc de la RAM, ni du PIC. Et à première vue rien sur le sujet sur le web.
Alors si qqn à des idées....

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 06-07-2011 08:01

Le montage fonctionne à la perfection depuis des semaines. Vu le peu de retour, je vais être obligé de faire l'impasse sur l'explication des tempos. Dommage, mais l'objectif est atteint, c'est l'essentiel.
Le montage a été un peu plus finalisé: alimentation à partir de 24VDC, convertisseur 5VDC sur base de MC34063, amélioration de l'alimentation de la RAM... Comme je le disais, cela fonctionne très bien. Le montage allant vers sa vraie vie, il a commencé à prendre son autonomie. Le cordon vers l'ICD3 a été débranché... et là, ca ne va plus. Enfin, tout fonctionne, mais les valeurs lues dans la ram sont du n'importe quoi.
Le défaut disparait dès que l'on connecte le programmateur alimenté (via usb) (mais pas nécessairement relié à MPLAB).
Que peut induire l'ICD qui explique cette différence ?

obdh

229 messages

Habitué
Habitué

Read post 06-07-2011 08:30

L'ICD relie la masse du PC et celle du montage. Le PC étant normalement à la terre (sauf portable sur batterie), la masse du montage se retrouve à la terre.
Donc, câblage de la liaison série certainement incorrecte. Je n'ai pas relu, mais une erreur commune avec les liaisons différentielles est de croire que la liaison de masse entre les deux équipements est inutile, ce qui est faux.

petard

55 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 06-07-2011 11:54

J'ai fais le test avec le montage alimenté par batterie et le PC portable deconnecté du secteur : même châtiment !
Cela ne m'etait d'ailleurs jamais arrivé avec des montages du meme type, mais sur des PIC16

Loblick

447 messages

Habitué
Habitué

Read post 06-07-2011 12:19

Et l'alimentation de l'ICD, ne serait-elle pas elle qui fait le rebouclage?

Sinon, regarder du côté de l'alim et du reset!

RISC

54 messages

Visiteur occasionnel
Visiteur occasionnel

Read post 09-07-2011 14:44

Salut,

Montres-nous le schéma électronique à jour de ton système.

Quelles valeurs as-tu programmées dans les bits de configuration ?
(cela doit être DANS ton programme)

a+

Veuillez vous identifier avant de répondre ou pour vous abonner à cette discussion