Professional Documents
Culture Documents
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
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. }