Buscamos un experto para escribir el programa de automóvil inteligente Freescale (puede sumar mil puntos)
De hecho, sólo el programa es inútil. El programa y el hardware deben combinarse. Por ejemplo, utilizar PT0 en el hardware y PT1 en el programa ciertamente no logrará el propósito esperado. El siguiente es un programa de la Universidad Jiao Tong de Shanghai.
Main.c
#include lt; hidef.hgt /* definiciones y macros comunes */
#include mc9s12db128.hgt; información derivada */
#pragma LINK_INFO DERIVATIVE "mc9s12db128b"
#include "define.h"
#include "init.h"
// variable utilizada en el proceso de vídeo
volatile unsigned char image_data[ROW_MAX][LINE_MAX]; // matriz de datos de la imagen
unsigned char black_x[ROW_MAX]; Matriz unidimensional
fila de caracteres unsigned; // posición x de la matriz
línea de caracteres unsigned // posición y de la matriz
unsigned; int row_count; // contador de filas
unsigned char line_sample; // usado para contrarrestar en AD
unsigned char row_image
unsigned char line_temp; variable utilizada en la transferencia de datos
unsigned char sample_data[LINE_MAX] ; // utilizada para guardar la matriz unidimensional obtenida en
interrupción
// las variables a continuación son usado en medida de velocidad
Pulso de caracteres sin firmar[5] // usado para guardar datos en el proceso PA
Contador de caracteres sin firmar // contador temporal en detección de velocidad
Unsigned char cur_speed; // velocidad actual
stand corto;
datos cortos;
curva de char unsigned // válvula usada para decidir directamente; o gire
Short Bounds(datos cortos);
Short FuzzyLogic(stand corto);
/*----------- -------------------------------------------------- --------------*\
receive_sci
\*---------------- -- --------
-------------------------------------------------- */
unsigned char recibir_sci(void) // recibir datos a través de sci
{ unsigned char sci_data;
while(SCI0SR1_RDRF!=1); p>
p>
sci_data=SCI0DRL;
devolver sci_data;
}
/*--------- ----- --------------------------------------------- ----- -*\
transmit_sci
\*---------------- -------------------------------------------------- -- -------*/
void transmit_sci(unsigned char transmit_data) // envía datos a través de sci
{
while(SCI0SR1_TC! =1 );
mientras(SCI0SR1_TDRE!=1);
SCI0DRL=transmitir_datos;
}
/**** ** ************************************************* *** **********************
***/
/*------ --- ----------------------------------------------- --- ------------------*\
abs_sub
\*---------- ---- ---------------------------------------------- ---- ------------*/
carácter sin firmar abs_sub(carácter sin firmar num1, carbón sin firmar num2)
{ diferencia de caracteres sin firmar;
if(num1gt;=num2){
difference=num1-num2;
}else{
difference=num2-num1;
}
diferencia de devolución;
}
void pwm_set(unsigned int dutycycle)
{ p>
PWMDTY1=dutycycleamp;0x00FF;
PWMDTY0=dutycyclegt;gt;8;
}
void get_black_wire(void) // solía extraiga el cable negro
{ unsigned char i;
for(row=0; rowlt; ROW_MAX; row){
for(line=LINE
_MIN; linelt; LINE_MAX-3; línea ){
if(image_data[fila][línea]gt; image_data[fila][línea 3] VÁLVULA){
para(i =3;ilt;10;i){
if(image_data[fila][línea i] VALVElt;image_data[fila][línea i 3]){
black_x[fila ]=línea i/2 2;
i=10;
}
}
línea=LINE_MAX;
} más{
//black_x[row]=(black_x[row]/45)*78;
}
}
}
}
/*---------------------- -------------------------------*\
control_velocidad
\*--------------------------------- -------- ---------------------------------*/
void speed_control(void)
{
suma int sin signo, promedio
suma=0
for(fila= 0; ; rowlt; FIRST_FIVE; fila ){
suma=suma black_x[fila];
}
average=sum/FIRST_FIVE;
curva=0;
for(row=0;rowlt;FIRST_FIVE;fila)
{
curva=curva abs_sub(black_x[fila], promedio );
if(curvegt;CURVE_MAX){
curve_flag=0;
velocidad=low_speed;}
else{< / p>
bandera_curva=1;
velocidad=alta_velocidad;
}
}
}
/*----------------------------------------------- ----------------------------------*\
control_de_dirección
\*- -------------------------------------------- ------ -----------------------*/
void steer_control(void)
{ unsigned int dutycycle ;
unsigned char video_center;
coeficiente unsigned int;
int E, U //actual
estático int e=0 ;
video_center
=(LINE_MIN LINE_MAX)/2;
stand=abs_sub(negro_x[1] negro_x[9], 2*negro_x[5]);
E=video_center-black_x[8 ];
coeficiente=30 1*FuzzyLogic(stand);
U=coeficiente*E;
dutycycle=Bounds(centro U);
pwm_set(dutycycle);
}
// asegúrate de que esté dentro de los límites
short Bounds(short data){
if(datagt;right_limit){
datos = right_limit;
}
if(datalt;left_limit){
datos = límite_izquierdo;
}
devolver datos;
}
Vid speed_get(void)
{
Temperatura de caracteres sin firmar;
Contador;
Temp=PACN1;
cur_speed=temp-pulse[counter-1];
pulso[counter-1]=temp;
if(counter==5)
{
counter=0; p>
if(contador==5)
{
contador=0;
p>
}
}
Vid set_speed(caracter sin firmar velocidad_deseado)
{
If(desired_speedlt;cur_speed)
{
PWMDTY2=baja_velocidad;
}
De lo contrario
{
PWMDTY2 =alta_velocidad;
}
}
/****************************** ******* ******************************************** **** p>
*\
Principal
\************************ *** ********************************************** ** ****
*/
void main(void) {
// función principal
init_PORT() ; p>
// inicialización del puerto
init_PLL();
// configuración del PLL
init_ECT();
init_PWM();
// INICIALIZACIÓN PWM
init_SPEED();
init_SCI();
for(; ;) {
if(field_signal==0){ // par-gt<
/p>
mientras(field_signal==0);
row_count=0;
row_image=0;
Habilitar interrupciones;
while(row_countlt;ROW_END){
get_black_wire();
speed_control();
steer_control();
}
DisableInterrupts;
}
else{ // impar-gt; par
mientras(field_signal==1); p>
p>
row_count=0;
row_image=0;
Habilitar interrupciones;
while(row_countlt;ROW_END){ p>
get_black_wire();
speed_control();
steer_control();
}
Desactivar interrupciones; p>
}
/* transmit_sci('x');
for(row=0; rowlt; ROW_MAX; fila){
transmit_sci (black_x[fila] );
}
transmitir_sci(curva);
*/
}
}
interrumpir 6 void IRQ_ISR()
{
row_count;
if((row_countgt;ROW_START)amp;amp; (row_countINTERVAL==0 )amp;amp;(row_imagelt;ROW_MAX))
{
init_AD();
for(line_sample=0;line_samplelt; LINE_MAX;line_sample ){
while(!ATD0STAT1_CCF0); // ESPERA A QUE FINALICE LA TRANSFORMACIÓN
sample_data[line_sample]=signal_in; // transferencia A/D
} p>
ATD0CTL2=0x00;
row_image;
}
if((row_countgt;ROW_START)amp;amp;( row_countINTERVAL==2) amp;amp;(row_imagelt;ROW_MAX
1)){
for(line_temp=0;line_templt;LINE_MAX;line_temp){
image_data[row_image- 1][line_temp]=sample_data[line_temp];
}
}
}
/// ///// ////////////////////////////////////////////// ///////// /////////////
////////////////////////////////////////////////// //// ///////////////////
// EL FINAL
//
//// //////////////////////////////////////////////// //////// /////////////////////////////////////////// //////////// //////////////////////////////////////
Define.h // todas las macros están definidas en este archivo de encabezado
/*---------------------- ----------------------- --------------------------- -------------*\
La macro debe usarse en la muestra de video
\*----------- ----------------------- --------------------------- ---------------*/
/////////////////////////// /////
#define signal_in ATD0DR0L // señal de video: modo alineado a la derecha,
// solo usa 8 bits bajos en el resultado de conversión ATD
Registros
#define field_signal PTT_PTT2 // la señal de campo se envía a PortT_bit2
#define LINE_MIN 12 // primera pinta efectiva en cada fila
#define LINE_MAX 78 // número de puntos muestreados en cada fila
#define ROW_MAX 10 // número de filas necesarias para muestrear en cada
imagen
#define ROW_START 50 // comenzar a muestrear desde el inicio de la línea
#define ROW_END 300 // finalizar el indicador de muestreo
#define INTERVAL 20 // intervalo entre filas efectivas
#define VALVE 24 // válvula para decidir pista negra o pista blanca
#define FIRST_FIVE 5
/*--------------- -------------------------- ------------------------ -*\
Variables de servocontrol p>
\*------------------- ---------------
---------------------------------*/
#define límite_izquierdo 7400 //
#define centro 6400 //
#define límite_derecho 5400 //
//#define coeficiente 30 // (IZQUIERDA -DERECHA)/(LINE_MAX-LINE_MIN)
/*-------------------------------- -------------------------------------------------- *\
Variable de control de velocidad
\*--------------------------- ------- ------------------------------------------- -------*/
#define curve_flag PORTE_BIT2 // indica línea recta o no
#define speed PWMDTY2 // velocidad del auto
#define CURVE_MAX 24 // válvula para decidir vía recta o no
p>#define high_speed 120 // velocidad utilizada en vía recta
#define low_speed 100 // velocidad utilizada en el turno
/*------- -------------------------------- ------------------ ------------------*\
definir código de salto; interruptor; Led
\*----- --------------------------------- ----------------- ---------------------*/
#definir JP4_1 PTT_PTT7 // JP4
#definir JP4_2 PTT_PTT6 p>
#definir JP4_3 PTT_PTT5
#definir JP4_4 PTT_PTT4
#definir JP4_5 PTP_PTP4 p>
#define JP4_6 PTP_PTP5
# define JP4_7 PTP_PTP6
// define el interruptor de código
#define RP1_1 PTM_PTM0
#definir RP1_2 PTM_PTM1
#definir RP1_3 PTM_PTM2 p>
#definir RP1_4 PTM_PTM3
#definir RP1_5 PTM_PTM4
#definir RP1_6 PTM_PTM5 p>
#definir RP1_7 PORTAD0_PTAD4
#definir RP1_8 PORTAD0_PTAD3
// d
definir Led
#definir Led1 PORTA_BIT4
#definir Led2 PORTA_BIT5
#definir Led3 PORTA_BIT6
#definir Led4 PORTA_BIT7
Init.c // incluye función inicial en este archivo
#include lt; hidef.hgt /* definiciones y macros comunes */
#include lt; hgt; /* información derivada */
#include "define.h" /* todas las macros incluidas */
#include "init.h" /* todas las funciones de inicio incluidas * /
#pragma LINK_INFO DERIVADA "mc9s12db128b"
/*-------------------- -------------------------------------------------- *\
init_PLL
\*------------------------------- --- ----------------------------------------------- -*/
void init_PLL(void)
// configuración del PLL
{
REFDV=3;
SYNR= 7; // periodo de bus=16Mhz*(SYNR 1)/(REFDV 1)
while(0==CRGFLG_LOCK // espera a que VCO se estabilice
CLKSEL=0x80 ;
// abrir PLL
}
Void init_ECT(void);
{
TIOS_IOS3= 0; // establece PT3 como captura de entrada
TCTL4=0b11000000; // establece pt3 como cualquier borde activado
ICPAR_PA1EN=1; habilitado
}
/*-------------------------------- -------- ----------------------------------*\
init_PORT
\*--------------------------------- --------- ----------------------------------*/
void init_PORT(void) // inicialización del puerto
{
DDRT_DDRT2=0;
// El puerto M1 funciona como señal de campo par-impar p>
entrada
t
DDRJ_DDRJ6=1;
// Puerto J6 habilitado 33886 0 habilitado
// Puerto LED
DDRA_BIT4 =1;
DDRA_BIT5 =1;
DDRA_BIT6 =1;
DDRA_BIT7 =1;
INTCR_IRQE =1 // Seleccionar IRQ solo sensible al borde;
INTCR_IRQEN=1; // Habilitación de IRQ externa
//Instrucción de salida JP4_1 PTT_PTT0
DDRT_DDRT7=1;
DDRT_DDRT6=1 ;
DDRT_DDRT5=1;
DDRT_DDRT4=1;
DDRP_DDRP4=1; //PTP_PTP0
DDRP_DDRP5=1; p>
p>
DDRP_DDRP7=1;
}
/*------------------- -------------------------------------------------- -- --*\
init_AD
\*--------------------- -------------------------------------------------- --*/
void init_AD(void)
// inicializar AD
{
ATD0CTL2=0xC0;
// abrir AD, borrado rápido, sin modo de espera, inhibir el despertar externo, inhibir la interrupción
ATD0CTL3=0x08;
// una transformación en una secuencia, sin FIFO, continuar transformando en modo congelado
ATD0CTL4=0x81;
// Precisión de 8 bits, dos relojes, ATDClock=[BusClock*0.5]/[PRS 1]; , divider=4;
BusClock=8MHZ
ATD0CTL5=0xA0; // alineado a la derecha, sin signo, canal único,
canal 0
ATD0DIEN=0x00 ; // inhibir entrada digital
}
/*---------------------- ---- ---------------------------------------------- ----* \
init_PWM
\*--------------------- ----- --------------------------------------------- -----*/
void init_PWM(void)
// inicio de PWM
alize
{
PTJ_PTJ6 = 0; // "0" habilita el motor 33886, "1" lo deshabilita
PWME = 0x00 // PWW está deshabilitado;
PWMCTL_CON01 = 1; // combinar PWM0, 1
PWMPRCLK = 0x33; // A=B=32M/8=4M
PWMSCLA = 100; // SA=A/2/100=20k
PWMSCLB = 1; // SB=B/2/1 =2000k
PWMCLK = 0b00011100 // PWM0, 1- A; PWM2, 3-SB; PWM4-SA
PWMPOL = 0xff; // Servicio=Tiempo alto
PWMCAE = 0x00; >PWMPER0 = 0x4e;
PWMPER1 = 0x20;
// 20000 = 0x4e20; Frecuencia=A/20000=200Hz
PWMDTY0 = 0x18;
PWMDTY1 = 0x6a; // inicializa PWM
PWME_PWME1 = 1; // habilita la dirección
PWMDTY2 = 20 // Ciclo de trabajo
PWMPER2; = 200; // Frecuencia=SB/200=10K
PWME_PWME2 = 1; // habilita el motor
}
/*------ -------------------------------------------------- -----------*\
init_SPEED
\*---------- - -------------------------------------------------- --------------*/
void init_SPEED(void) {
DDRM_DDRM0 =0; //cambio de código 1 en RP1 p >
DDRM_DDRM1 =0; //codificar el interruptor 1 en RP1
DDRM_DDRM2 =0; //codificar el interruptor 1 en RP1
DDRM_DDRM3 =0; RP1
DDRM_DDRM4 =0; //código del interruptor 1 en RP1
DDRM_DDRM5 =0; //código del interruptor 1 en RP1
ATD0DIEN_IEN4 = 1; interruptor de código 1 en RP1, habilitar entrada digital PAD4
ATD0DIEN_IEN3 = 1; //interruptor de código 1 en RP1, habilitar entrada digital PAD3
if(RP1_1==
1) {
velocidad= alta_velocidad 2*(RP1_2*10 RP1_3*5 RP1_4*2 RP1_5*2 RP1_6 RP1_7 RP1_8);
}
else{
velocidad= alta_velocidad -2*(RP1_2*10 RP1_3*5 RP1_4*2 RP1_5*2 RP1_6 RP1_7 RP1_8);
}
}
/********************************************* *** **********************************
***/
/*-------------------------------------------- ---- ----------------------------*\
init_SCI
\ *--- ---------------------------------------------- ---- -----------------------*/
void init_SCI(void) // inicializar SCI
{
SCI0BD = 104; // tasa de bode=32M/(16*SCI0BD)=19200
SCI0CR1=0x00; 0b00001100;
SCI0CR2=0b00001100;
SCI0BD = 104; p>
}
Init.h
void init_PLL( void);
void init_AD(void);
void init_PWM(void);
void init_SPEED(void);
void init_SCI(void);
void init_PORT(void);
Void init_ECT(void);
Fuzzy.asm // Código de lógica difusa S12
RAM: sección
; Conjuntos de membresía difusa
; variables de membresía de entrada
fuzvar ausente
fuzvar: ds.b 5; entradas
Z: equ 0; indica de línea recta
VS: equ 1; girar ligeramente
S: equ 2; p>
BB: equ 3; un gran giro
VB: equ 4 ; un gran giro
variables de membresía de salida
fuzout ausente
fuzout: ds.b 4; salidas
permanecen: equ 5; sin cambios en kp
pequeño: pequeño cambio en kp
grande: ecuación 7; gran cambio
e en Kp
muy_grande: equ 8; cambio muy grande en kp
EEPROM: sección
; b 0, 35, 0, 8; indicar de línea recta
dc.b 0, 69, 8, 8; girar ligeramente
dc.b 35, 104, 8, 8; ; girar un poco
dc.b 69,138,8,8; un giro grande
dc.b 104,255,8,0; reglas: ;
construcción de regla
dc.b Z, $FE, permanecer, $FE
dc.b VS, $FE , poco, $ FE
dc.b S, $FE, grande, $FE
dc.b BB, $FE, grande, $FE
dc.b VB , $FE, very_big, $FE
dc.b $FF; fin de la regla
addingleton:
dc.b 0, 1, 2, 3; configuración del peso
ausentry FuzzyLogic
FuzzyLogic:
pshx
ldx #s_tab
ldy #fuzvar
mem; número de mem indica el número de entradas
mem
mem
mem
mem
ldab #4; número de conjuntos de membresía difusa de salida
cloop:
clr 1, y; borrar variables difusas de salida
dbne b, cloop
ldx #rules
ldy #fuzvar
ldaa #$FF
rev
ldy #fuzout
ldx #addsingleton
ldab #4
wav
ediv;
tfr y, d; devolver dpower
pulx
rts