Comment programmer un CAN d'un microcontroleur 8051 ? - C - Programmation
Marsh Posté le 21-05-2006 à 13:26:39
Alors voilà, nous avons réussi à programmer le CAN en C le CAN du microcontroleur. Vient maintenant l'étape où nous devons convertir numériquement les données arrivant du mirco "rue". Nous devons utiliser le même CAN que précédemment car ce dernier est un CAN 12 bits. Et là on a un peu de mal à le faire car il faut que les signaux issus de chaque microphone soit numérisé quasiment en même temps pour pouvoir les comparer ensuite à un instant t.
Voici le code que nous avons fait :
//-----------------------------------------------------------------------------
// Temp_3.c
//-----------------------------------------------------------------------------
// Copyright (C) 2004 Silicon Laboratories, Inc.
//
// AUTH: BW
// DATE: 19 JUL 01
//
// This program prints the C8051F020 die temperature out the hardware
// UART at 9600bps. Assumes an 22.1184MHz crystal is attached between
// XTAL1 and XTAL2.
//
// The ADC is configured to look at the on-chip temp sensor. The sampling
// rate of the ADC is determined by the constant <SAMPLE_RATE>, which is given
// in Hz.
//
// The ADC0 End of Conversion Interrupt Handler retrieves the sample
// from the ADC and adds it to a running accumulator. Every <INT_DEC>
// samples, the ADC updates and stores its result in the global variable
// <temperature>, which holds the current temperature in hundredths of a
// degree. The sampling technique of adding a set of values and
// decimating them (posting results every (n)th sample) is called 'integrate
// and dump.' It is easy to implement and requires very few resources.
//
// For each power of 4 of <INT_DEC>, you gain 1 bit of effective resolution.
// For example, <INT_DEC> = 256 gain you 4 bits of resolution: 4^4 = 256.
//
// Also note that the ADC0 is configured for 'LEFT' justified mode. In this
// mode, the MSB of the ADC word is located in the MSB position of the ADC0
// high byte. Using the data in this way makes the magnitude of the resulting
// code independent of the number of bits in the ADC (12- and 10-bits behave
// the same).
//
// Target: C8051F02x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//-----------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define BAUDRATE 115200 // Baud rate of UART in bps
#define SYSCLK 22118400 // SYSCLK frequency in Hz
#define SAMPLE_RATE 10000 // Sample frequency in Hz
#define INT_DEC 256 // integrate and decimate ratio
sbit LED = P1^6; // LED='1' means ON
sbit SW1 = P3^7; // SW1='0' means switch pressed
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void ADC0_Init (void);
void Timer3_Init (int counts);
void ADC0_ISR (void);
void _tempo(int j);
//-----------------------------------------------------------------------------
// Global VARIABLES
//-----------------------------------------------------------------------------
long result; // ADC0 decimated value
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void) {
long son; // son
// degree C
// integer and fractional portions of
// son
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
SYSCLK_Init (); // initialize oscillator
// initialize crossbar and GPIO
Timer3_Init (SYSCLK/SAMPLE_RATE); // initialize Timer3 to overflow at
// sample rate
ADC0_Init (); // init ADC
AD0EN = 1; // enable ADC
EA = 1; // Enable global interrupts
while (1) {
EA = 0;
_tempo(1000);
// disable interrupts
son = result;
_tempo(1000);
EA = 1; // re-enable interrupts
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an 22.1184MHz crystal
// as its clock source.
//
void SYSCLK_Init (void)
{
int i; // delay counter
OSCXCN = 0x67; // start external oscillator with
// 22.1184MHz crystal
for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms)
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Configure ADC0 to use Timer3 overflows as conversion source, to
// generate an interrupt on conversion complete, and to use left-justified
// output mode. Enables ADC end of conversion interrupt. Leaves ADC disabled.
//
void ADC0_Init (void)
{
ADC0CN = 0x05; // ADC0 disabled; normal tracking
// mode; ADC0 conversions are initiated
// on overflow of Timer3; ADC0 data is
// left-justified
REF0CN = 0x03; // enable temp sensor, on-chip VREF,
// and VREF output buffer
AMX0SL = 0x00; // Select AIN0 as ADC mux output
ADC0CF = (SYSCLK/2500000) << 3; // ADC conversion clock = 2.5MHz
ADC0CF |= 0x00; // PGA gain = 1
EIE2 |= 0x02; // enable ADC interrupts
}
//-----------------------------------------------------------------------------
// Timer3_Init
//-----------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK as its time base.
//
void Timer3_Init (int counts)
{
TMR3CN = 0x02; // Stop Timer3; Clear TF3;
// use SYSCLK as timebase
TMR3RL = -counts; // Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 &= ~0x01; // disable Timer3 interrupts
TMR3CN |= 0x04; // start Timer3
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
//
// ADC0 end-of-conversion ISR
// Here we take the ADC0 sample, add it to a running total <accumulator>, and
// decrement our local decimation counter <int_dec>. When <int_dec> reaches
// zero, we post the decimated result in the global variable <result>.
//
void ADC0_ISR (void) interrupt 15
{
// integrate/decimate counter
// we post a new result when
// int_dec = 0
static long accumulator=0L; // here's where we integrate the
// ADC samples
AD0INT = 0; // clear ADC conversion complete
// indicator
accumulator = ADC0; // read ADC value and add to running
// total
result = accumulator >> 8;
}
void _tempo(int j)
{ int k;
int a=0;
for (k=0;k<j;j++)
a=a;
}
Comment feriez vous pour réussir à numériser deux signaux quasiment en même temps cad scanner un port, stocker, sa valeur, scanner tt de suite après un autre port, stocker sa valeur etc... ?
Merci
Marsh Posté le 23-05-2006 à 12:31:58
reup
Marsh Posté le 23-05-2006 à 14:02:46
tonio10 a écrit : Qq'un peut il m'aider pour la programmation en assembleur ou en C le CAN du microcontroleur SVP ??? |
C'est pas une problème de C, mais de conception. Ben faut lire la doc...
http://www.silabs.com/public/docum [...] _Short.pdf
http://www.silabs.com/public/docum [...] 51F02x.pdf
http://www.mytutorialcafe.com/down [...] amming.pdf
etc. est ton ami...
Une fois que tu sais quels registres il faut programmer, lesquels il faut surveiller et à quel rythme, tu peux écrire le bon algorithme et le coder en C.
On est pas censé connaître le fonctionnement interne de tous les microcontroleurs du monde... Par contre, on peut t'aider à écrire du C correct. Le problème du C51, c'est qu'il n'est pas portable...
Marsh Posté le 14-12-2006 à 14:22:30
bonjour tous
Voila je voudrais écrire un programme en C pour un motorola 68HC12. Le probléme c'est que je n'ai étudié la programmation d'un microcontroleur en Assembleur et je n'arrive pas à faire la transition.
Par exemple comment écrire en langage C le MOVE et LEA.
Si vous pouviez m'aider faire la traduction de Move en C et LEA aussi ça serait génial.
Marsh Posté le 14-12-2006 à 17:58:04
soma14 a écrit : Voila je voudrais écrire un programme en C pour un motorola 68HC12. Le probléme c'est que je n'ai étudié la programmation d'un microcontroleur en Assembleur et je n'arrive pas à faire la transition. |
C'est pas comme ça que ça marche. Si tu veux écrire en C, il te faut apprendre le langage C, et ce indépendamment de la plateforme que tu utilises. Des références sur mon site...
Ensuite, il te faudra lire la doc de ton compilateur pour apprendre à réaliser certaines opérations particulières.
P.S. çasefépa de cannibaliser un thread existant.
Marsh Posté le 21-05-2006 à 11:09:27
Bonjour @ tous, voilà j'ai un projet d'électronique à rendre pour juin. Notre sujet consiste à réaliser un système d'interphone. On dispose de 2 micros, l'un est placé ds une maison par ex et l'autre dans la rue.
Le micro de la rue sert juste à capter les bruits de la rue alors que celui de la maison sert à acquérir la voix d'un mec qui parle. Le but est de réguler l'interphone placé dans la rue en fonction du niveau du bruit ambiant dans la rue.
Pour la partie électronique je n'ai pas trop de mal, mais pour ce qui est de la programmation du microcontroleur 8051 (que l'on utlise en TP) j'ai plus de mal. Pour l'instant on a un signal sinusoïdale centré entre 0 et 2.5V qui arrive sur un CAN du 8051. Le but est de numériser ce signal car ensuite nous pourrons le comparer avec le signal numérisé issu du bruit de la rue. Avec un potebtiomètre numérique on pourra donc réaliser l'asservissement.
Qq'un peut il m'aider pour la programmation en assembleur ou en C le CAN du microcontroleur SVP ???
Merci bcp
Message édité par tonio10 le 23-05-2006 à 11:19:08
---------------
Be myself, I have nothing to prove...