You are on page 1of 13

Proyecto Final Diseo Digital con Microcontroladores

Integrantes: Juan Carlos Vargas Sosa 20102005046 Juan Sebastin Rojas Sabogal 20102005097 Sebastin Vargas Gantiva 20102005089

Universidad Distrital Francisco Jos de Caldas Diseo digital con Microcontroladores Bogot D.C 2013

PLANTEAMIENTO DEL PROBLEMA


Disear y construir un sistema de disparo de proyectiles (can). Para el disparo del proyectil se debern ajustar previamente los ngulos de elevacin 0 a 90 haciendo uso de un acelermetro y de rotacin de 0 a 360 respecto al Norte magntico de la Tierra por lo tanto ser necesario el uso de una brjula digital, los cuales debern ser ingresados por medio de un teclado y visualizados en una LCD (en cada caso la resolucin debe ser de 1). Luego de ajustados los parmetros anteriores se tendr una tecla definida por cada grupo de trabajo para el disparo del proyectil (por seguridad el proyectil debe ser un elemento que no pueda causar ningn tipo de dao, por ejemplo un ping pon). El corazn del proyecto como es obvio debe ser un microcontrolador de la familia HC08 de Freescale, ms todos los elementos adicionales que crean necesarios. El programa deber ser escrito en lenguaje C.

ANLISIS DEL PROBLEMA


Observando el problema tenemos inicialmente que reconocer que la solucin est basada en una parte correspondiente a la programacin y otra correspondiente a la maqueta. El primer detalle a tener en cuenta era el manejo de los perifricos. Se haca necesario el uso de motores para realizar el la rotacin vertical y horizontal del can, para esto se haca necesario el manejo de puertos configurados como salida para su manejo. En principio se crey que el uso del acelermetro deba ser independiente de la brjula, pero esto pudo ser simplificado, dado que la brjula tiene pines de salida correspondientes a un acelermetro interno. Debido a que se vena trabajando el manejo de la LCD en Assembler fue necesario hacer traduccin del cdigo ya trabajado en las prcticas pasadas. Esta traduccin fue necesaria de igual manera para el manejo del teclado. Una vez implementados los mtodos para el manejo de cada perifrico, se debera realizar la interfaz con el usuario utilizando la LCD y el teclado, de esta manera, se obtendran los valores de inclinacin y rotacin deseados, una vez obtenidos, el programa principal hara las tareas necesarias para satisfacer las necesidades del usuario y le indicara en pantalla que el can ya est listo para ser disparado, al momento de oprimir un botn, se disparara. Ahora, el ltimo detalle que quedara por solucionar es el del disparo del can.

MODELO DE SOLUCION
Procedemos a crear variables, datos y dems junto con la configuracin de puertos, donde usaremos todo el puerto A (PTA) para el manejo de la LCD. Dado que el puerto D (PTD) posee los pines para la interrupcin por teclado, se hizo uso del teclado matricial en dicho puerto. Se utilizaron 2 motores, uno para la inclinacin y otro para la rotacin, uno de ellos estaba ubicado en los pines PTC4 a PTC7, el otro se ubic en PTB4 a PTB7, cada uno de ellos destinados a la conexin de los bobinados (A+, B+, A-, B-). Se decidi que la brjula iba a comunicarse con el microcontrolador a travs de comunicacin serial. Para ello se conect el pin de modo de la brjula a tierra, con lo cual se seleccionaba el Serial Mode. Los pines Tx y Rx se conectaron a los pines PTB2/TxD y PTB3/RxD, en donde el pin de transmisin de datos iba a su vez conectado a una resistencia de pull up de 10k. Dado que la LCD hasta ahora solo tena definidos los bits D0D7, haca falta conectar los pines de reset y enable los cuales fueron destinados a los pines PTC3 y PTC2 respectivamente. Se emple el integrado ULN2003, que corresponde a un arreglo de transistores Darlington de alta corriente y alto voltaje como driver para controlar los motores paso a paso PTB4 a PTB7) conectados a (1B,2B,3B,4B) y (A+, B+, A-, B-) conectados a (1B,2B,3B,4B) y los pines COM conectados a 12V para as alimentar y suministrar potencia a los motores. Con respecto al cdigo, se crearon varios mtodos o funciones con el fin de simplificar y reutilizar cdigo. Se cre una funcin llamada LCD_Config que tena el obtetivo de configurar la LCD. Se cre una funcin llamada Modo que tiene un parmetro que dependiendo de su valor (1-0) define si el dato enviado corresponde a un dato o a un comando. Se cre una funcin llamada Print que tiene dos parmetros de entrada (unsigned char posicion, char texto) el primer parmetro corresponde a la posicin de la LCD y el siguiente un arreglo de comandos que es lo que se va a escribir en l LCD Se cre una funcin llamada Print_num la cul es una funcin que descompone un byte en caracteres tipo ascci y los imprime en la lcd, tiene tres parmetros (unsigned char posicion, unsigned int pow, unsigned int num) el primero de ellos corresponde a la posicin en donde

se desea escribir, el segundo define la potencia de diez que corresponde a el nmero de caracteres que se desea escribir 3- el byte. Se cre una funcin llamada Mover la cual corresponde a una funcin con la cual se permite el movimiento de los motores y tiene tres parmetros (unsigned char motor, unsigned char direccion, unsigned long pasos), en los cuales el primero de ellos define cual de los dos motores disponibles se quiere mover, el segundo define la direccin adelante-atrs y el tercero el nmero de pasos que quiere mover.

A continuacin se definieron las interrupciones para el manejo del teclado que tiene como principal caracterstica que no puede tener parmetros ni de entrada ni de salida [interrupt 15 void KBI(void){], por lo tanto se definieron tres variables externas en las cuales se recupera el valor digitado. Estos son: unsigned char key; unsigned int datain, flag; As, en key se recupera el valor ASCII digitado directamente. Flag es una potencia de 10 que se ingresa para determinar cuntos dgitos pueden ser recuperados y datain obtiene al final el numero digitado. Se cre una funcin llamada Delay, la cual es una funcin que tiene un parmetro de entrada el cual define un retraso en milisegundos.

En el main se definen los puertos, entradas salidas, se configura LCD, se configura el modulo serial, se configuran las interrupciones y dentro del bucle infinito se crea una interfaz con el usuario en la cual se solicitan los valores de los grados de inclinacin, solo valores validos entre 0-85 estn permitidos por la brjula y la rotacin entre 0-360. Despus se inicia la lectura del ngulo del can indicado por la brjula y se mueve el motor un paso hasta que se consiga que el ngulo de inclinacin digitado sea el mismo ngulo brindado por la brjula. Luego se hace lo mismo pero con el ngulo de rotacin respecto al norte magntico de la tierra, valor que arroja la brjula Una vez ajustados estos dos parmetro se habilita una interfaz que permite el lanzamiento del pin pon y se activa con la tecla asterisco (*).

CONCLUSIONES
Gracias a la aplicacin de todos los conocimientos adquiridos del microcontrolador MC68HC9089AP16, se logr dar una implementacin satisfactoria a un problema planteado, que inclua y haca necesario el uso de gran parte de las caractersticas del microcontrolador. Se siguieron los 5 pasos sugeridos para darle solucin al problema planteado del can, se identificaron los detalles a los cuales se les deba dar mayor prioridad, tales como el manejo de los perifricos en C, el planteamiento de la maqueta, la distribucin de tareas y la evaluacin del tiempo necesario para solucionar cada fragmento del proyecto para as evitar retrasos o posibles faltas a la hora y momento definido para la entrega.

ANEXOS
1. ESQUEMA Y DISTRIBUCION DE PINES

2. CDIGO DEL CAON EN C 3. #include <hidef.h> /* for EnableInterrupts macro */ 4. #include "derivative.h" /* include peripheral declarations */ 5. 6. #define Disable_COP() CONFIG1_COPD = 1 7. #define LCD() PTA 8. #define Enable() PTC_PTC3 9. #define Reset() PTC_PTC2 10. 11. unsigned char x = 0x99, y = 0x99, key; 12. unsigned int datain = 0, flag; 13. 14. void Delay(unsigned long iteraciones){ 15. unsigned long i; 16. iteraciones = (iteraciones * 20)/7; //aproximacion en ms 17. for (i = 0; i < iteraciones; i++); 18. } 19. 20. void Modo(unsigned char StateReset){ 21. Reset() = StateReset; 22. Enable() = 0; 23. Delay(2); 24. Enable() = 1; 25. Delay(5); 26. } 27. 28. void Print(unsigned char posicion, char texto[]){ 29. unsigned int i; 30. LCD() = posicion; 31. Modo(0); 32. for (i = 0; texto[i] != '\0'; i++){ 33. LCD() = texto[i]; 34. Modo(1); 35. } 36. } 37. 38. void Print_Num(unsigned char posicion, unsigned int pow, unsigned int num){ 39. LCD() = posicion; 40. Modo(0); 41. 42. while (pow != 1){ 43. LCD() = num / pow + 48; //para enviar los numeros de 0 a 9 se suma 48

44. Modo(1); 45. num %= pow; 46. pow /= 10; 47. } 48. LCD() = num + 48; 49. Modo(1); 50. } 51. 52. void LCD_Config(void){ 53. Enable() = 1; 54. Delay(50); 55. LCD() = 0b00111000;/* funcion set 0b001 DL N F x x 56. DL = 0 DB a 4 bits, DL = 1 DB a 8 bits 57. N = 0 activa 1 linea, N = 1 activa 2 lineas 58. F = 0 activa matriz 5x7, F = 1 activa matriz 5x10 */ 59. Modo(0); 60. LCD() = 0b00000110;/* seleccion modo de operacion 0b000001 I/D S 61. I/D = 0 decrementa contador RAM, I/D = 1 incrementa contador RAM 62. S = 0 display estatico, S = 1 display se desplaza al escribir dato */ 63. Modo(0); 64. LCD() = 0b00001100;/* display on/off 0b00001 D C B 65. D = 0 display off, D = 1 display on 66. C = 0 cursor off, C = 1 cursor on 67. B = 0 cursor estatico, B = 1 cursor parpadea 68. 69. desplazamiento de cursor o display 0b0001 S/C R/L x x 70. S/C = 0 movimiento de cursor, S/C = 1 movimiento de display 71. R/L = 0 movimiento de display a izquierda, R/L = 1 movimiento de display a derecha */ 72. 73. Modo(0); 74. LCD() = 0b00000001;/* borrar display 75. cursor de inicio 0b0000001x ubica cursor en 0,0 */ 76. Modo(0); 77. Delay(20); 78. 79. /* 80. ubicar cursor 0b1 direccion deseada 81. posicion y + posicion x 82. linea 1: 0 83. linea 2: 0x40 84. linea 3: 0x14 85. linea 4: 0x54

86. 87. Print(0x80+0x02,"Microcontrolador"); 88. Print(0x80+0x40+0x05,"Freescale"); 89. Print(0x80+0x14+0x03,"MC68HC908AP16"); 90. */ 91. } 92. 93. interrupt 15 void KBI(void){ 94. unsigned char n = 0, in, out = 0x0E; 95. char teclado[] = "ABCD369#2580147*"; 96. // PT3 hasta PT0 a C1 hasta C4 y PT7 hasta PT4 a F1 hasta F4 97. 98. do { 99. PTD = out; 100. Delay(2); 101. in = PTD & 0xF0; 102. 103. if (in == 0x70) 104. break; 105. n++; 106. 107. if (in == 0xB0) 108. break; 109. n++; 110. 111. if (in == 0xD0) 112. break; 113. n++; 114. 115. if (in == 0xE0) 116. break; 117. n++; 118. 119. out <<= 1; 120. out++; 121. /* 122. out = 7; 123. char teclado[] = "147*2580369#ABCD"; 124. ... 125. 126. out = ~out; 127. out &= 0x0F; 128. out >>= 1; 129. out = ~out; 130. out &= 0x0F;

131. */ 132. 133. } while (n < 16); 134. 135. key = teclado[n]; 136. if (key >= '0' && key <= '9'){ 137. if (flag != 0){ 138. LCD() = key; 139. Modo(1); 140. } 141. 142. key -= 48; 143. datain += key * flag; 144. flag /= 10; 145. } 146. 147. PTD = 0; 148. Delay(100); 149. KBSCR_ACK = 1;/* cuando cambia de 0xF0 a 0xB0 por ejemplo se genera una interrupcion 150. si se oprimio 2 dentro de la interrupcion cambia de 0xB0 a 0xF0 151. y luego de 0xF0 a 0xB0 momento en el cual se genera otra interrupcion 152. que queda en espera */ 153. } 154. 155. void Mover(unsigned char motor, unsigned char direccion, unsigned long pasos){ 156. //direccion = 0 adelante, direccion = 1 atras 157. //motor = 0 port low, motor = 1 port high 158. unsigned int i, vel = 50; //60000/(rpm * numpasos) 159. unsigned char temp, comando; 160. 161. comando = motor == 0? x : y; 162. 163. for (i = 0; i <= pasos; i++){ 164. if (direccion == 0){ 165. //rotar a la derecha una vez; 166. temp = comando & 1; 167. comando >>= 1; 168. comando |= temp << 7; 169. } 170. if (direccion == 1){ 171. //rotar a la izquierda una vez;

172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216.

temp = comando & 0x80; comando <<= 1; comando |= temp >> 7; } if (motor == 0){ temp = comando & 0x10; PTC_PTC4 = temp == 0x10? 1 : 0; temp = comando & 0x20; PTC_PTC5 = temp == 0x20? 1 : 0; temp = comando & 0x40; PTC_PTC6 = temp == 0x40? 1 : 0; temp = comando & 0x80; PTC_PTC7 = temp == 0x80? 1 : 0; } else PTB = comando & 0xF0; Delay(vel); } if (motor == 0) x = comando; else y = comando; } void main(void){ unsigned int angle, pitch, incline, rotation; Disable_COP(); DDRA = 0xFF; DDRB = 0xF1; DDRC = 0xFF; DDRD = 0x0F; PTD = 0; PTB_PTB0 = 0; LCD_Config(); // Configuracion KBI INTSCR1_IMASK1 = 1; KBSCR_IMASK = 1; KBSCR_ACK = 1; KBSCR_IMASK = 0; KBIER = 0xF0;

217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261.

EnableInterrupts; // Configuracion SCI SCBR = 0b00000011; //Bd = 8, Pd = 1, vel = 9600bps SCC1_ENSCI = 1; //habilitar SCI SCC2_TE = 1; //habilitar Tx SCC2_RE = 1; //habilitar Rx for(;;) { LCD() = 1; Modo(0); Print(0x80,"Ingrese inclinacion"); do { Print(0xC0," "); LCD() = 0xC0; Modo(0); flag = 10; datain = 0; while (flag != 0); incline = datain; } while (incline > 85); Print(0x94,"Ingrese rotacion"); do { Print(0xD4," "); LCD() = 0xD4; Modo(0); flag = 100; datain = 0; while (flag != 0); rotation = datain; } while (rotation > 360); LCD() = 1; Modo(0); Print(0x80,"Espere por favor..."); Print(0x94,"Inclinacion "); do { while (SCS1_SCTE == 0); SCDR = 0x14; //lectura de inclinacion de 0 a 85 while (SCS1_SCRF == 0); pitch = SCDR;

262. Print_Num(0xA0,100,pitch); 263. if (incline > pitch) 264. Mover(0,0,1); 265. else 266. Mover(0,1,1); 267. } while (incline != pitch); 268. 269. Print(0x94," "); 270. Print(0x94,"Rotacion "); 271. 272. do { 273. while (SCS1_SCTE == 0); 274. SCDR = 0x13; //lectura del angulo de 0 a 3600 275. while (SCS1_SCRF == 0); 276. angle = SCDR * 256; //se multiplica para colocar SCDR en angle high 277. while (SCS1_SCRF == 0); 278. angle += SCDR; 279. angle /= 10; 280. 281. Print_Num(0x9D,100,angle); 282. if (rotation > angle) 283. Mover(1,0,1); 284. else 285. Mover(1,1,1); 286. } while (rotation != angle); 287. 288. LCD() = 1; 289. Modo(0); 290. Print(0x80,"Ahora puede disparar"); 291. Print(0xC0,"presionando *"); 292. 293. while (key != '*'); 294. PTB_PTB0 = 1; 295. Delay(500); 296. PTB_PTB0 = 0; 297. 298. Delay(1000); 299. } 300. }

You might also like