Practica : Programación en C
Parte A
1) Realizar un programa para intercambiar los contenidos de dos variables enteras.
2) Realizar un programa que declare las variables x, y, z, les asigne los valores 10, 20 y 30 e intercambie entre si sus valores de forma que el valor de x pasa a y, el de y pasa a z y el valor de z pasa a x (se pueden declarar variables auxiliares aunque se pide que se use el menor número posible).
3) Escriba un programa en C que emule el comportamiento de las puertas lógicas NAN, OR, NOT y XOR. Los datos de entrada son tres variables enteras, que solo pueden valer ser 0 o 1. Realice un programa por puerta.
4) Escriba un programa que pida al usuario 10 números enteros y multiplique el primero por uno, el segundo por dos y así sucesivamente. Debe entregar como salida la suma de las multiplicaciones.
5) Escriba un programa en C que tenga una función que reciba como argumento de que puerta lógica quiere emular su comportamiento y se comporte de acuerdo a ese argumento. Trabaje con lo logrado en el ejercicio 1.
6) Escriba un programa que lea por teclado diez números enteros distintos de cero y a continuación lea una secuencia de valores enteros indicando si están entre los diez valores leídos. Cuando se lea el valor cero, el programa finalizará.
7) Se ingresa por teclado la cantidad de agua caída, en milímetros día a día durante un mes. Se pide determinar el día de mayor lluvia, el de menor y el promedio
8) Realizar un programa que le presente al usuario un menú de opciones con las cuatro operaciones básicas (suma, resta, multiplicación, división). Según la operación elegida ingresará 2 números enteros, se realizará la misma y se mostrará por pantalla el resultado. El usuario podrá trabajar en el programa hasta que indique lo contrario. Recordar que la división por cero es indeterminada.
9) Leer 20 números enteros positivos. Mostrar el vector tal como fue ingresado y luego mostrar el vector ordenado en forma decreciente.
10) Realizar un programa que pida una temperatura en grados Celsius y la convierta a grados Fahrenheit mostrando en pantalla un mensaje del tipo xxx grados Celsius son yyy grados Fahrenheit. Recuerde que:
11) Se define TipoCiudad como un struct para almacenar la posición de una ciudad en una representación de dos dimensiones, es decir, en un plano.
struct TipoPunto{
double abscisa;
double ordenada;
}
struct TipoCiudad{
TipoPunto situacion;
char nombre[50];
};
Para almacenar varias ciudades, se construirá un vector de TipoCiudad. Se pide construir una función que, a partir de un vector de TipoCiudad y dado el nombre de una ciudad, reordene ascendentemente el vector atendiendo a la distancia euclídea del resto de las ciudades con respecto a la elegida. Por ejemplo, si elegimos "Granada", la ciudad con dicho nombre deberá ponerse como la primera componente del vector; la segunda será la ciudad más cercana a "Granada" y así sucesivamente. El prototipo de la función será:
void Reordenar (TipoCiudad ciudades[], int num_ciudades, const char nombre_ciudad_referencia[]);
Recordemos que la distancia euclídea entre dos puntos se define como la raíz cuadrada de la suma de los cuadrados de las diferencias de las abscisas y las ordenadas. No pueden usarse vectores auxiliares.
12) Una red de sensores inalámbrica intercambia mensajes entre sus nodos y esta comunicación tiene diferentes características. La comunicación puede ser broadcast o unicast , multihop o single hop, el mensaje se puede enviar o puede fallar su envío, y el mismo puede ser recibido o no. Escriba una función en C, que utilice un campo de bits, para representar que tipo de características tiene la comunicación y si se pudo establecer o no. Realice un programa que genere 6 valores al azar de un byte, y analice que tipo de comunicación se estableció. Muestre por pantalla como resultó cada comunicación.
Significado de cada bit: 0 broadcast, 1 unicast, 2 multihop, 3 single hop, 4 enviado, 5 no enviado, 6 recibido y 7 no recibido.
13) Escribir la función paridad_par que recibe un byte y retorna un byte. El byte devuelto debe ser igual al byte recibido o igual al byte recibido con el bit mas significativo modificado de forma tal que la configuración del byte entregado contenga un número par de unos.
14) Generar una función unsigned getBits(unsigned x,int p, int n) que retorne adjustado a derecha los n bits de x, más a la izquierda que la posición indicada por p. Asumir que el bit menos significativo de x, ocupa la posición cero 0 y que n y p siempre asumen valores positivos, por ejemplo:
getBits(x,4,3) deberá retornar los 3 bits que ocupen las posiciones 4, 5 y 6 dentro de x
15) Generar una función unsigned rightRot(unsigned x,int n) que rote a derecha los ultimos n bits de x. Asumir que el bit menos significativo de x, ocupa la posición cero y que n siempre asume valores positivos.
16) Generar una función unsigned setBits(unsigned x, int p) que setee adjustado a izquierda los p bits menos significativos de x. El resto de los bits deben ser cero Asumir que el bit menos significativo de x, ocupa la posición cero y que p siempre asume un valor positivo que debe ser menor o igual a 7.
Parte B
En los siguientes ejercicios debe asumirse:
que los 8 bits de una variable PORT_OUT representan sendas salidas digitales de un microcontrolador (MCU). El menos significativos es el bit0 y el mas significativo es el bit7. Estas salidas se consideran en los enunciados finalmente conectadas a sendos leds.
análogamente, que los 8 bits de una variable PORT_IN representan sendas entradas digitales. Estas entradas se consideran en los enunciados finalmente conectadas a sendos pulsadores.
que tanto PORT_IN como PORT_OUT operan con lógica positiva. Es decir, un "1" en un bit de la variable PORT_OUT ocasionará un valor eléctrico "alto" (activo, prenderá el led) en la salida del microcontrolador; un valor "alto" (activo, pulsador accionado) en una entrada producirá un "1" en el correspondiente bit de la variable PORT_IN.
Generar entonces:
Una función unsigned char LeerEntradas() de forma tal que devuelva el valor decimal correspondiente al numero binario representado por el estado de los bits de PORT_IN.
Una función void SetearSalidas(unsigned char work) de forma tal que se establezca PORT_OUT en correspondencia con los bits de work.
Una función void Inicializar() que setee parámetros que fuesen necesarios para el programa.
Importante: Luego de probar los ejercicios en forma simulada en un compilador, adaptarlos convenientemente teniendo en cuenta las variables definitivas a utilizar y el tipo de lógica conforme el microcontrolador destino. En la elección de salidas y entradas tener en cuenta también la disponibilidad física de las salidas y entradas y los componentes asociados (leds y switchs) acorde al kit de desarrollo a utilizar en la prueba del programa.
17) Realizar un programa que active (produzca valores "altos") en los bits de posición par de PORT_OUT y desactive los de posiciones impares.
18) Realizar un programa que sólo active un bit de PORT_OUT y vaya rotando dicho bit encendido indefinidamente. Cada rotación debe producirse cada T mseg, siendo T el tiempo necesario para ejecutar aproximadamente 300.000 instrucciones. Ejecutarlo variando en mas y menos el valor de 300.000.
19) Reelaborar el ejercicio 12 mostrando la codificación allí definida mediante leds.
20) Reelaborar y simular el problema 3 utilizando leds y pulsadores.
21) Modificar el programa 18 de forma tal que, si ningún bit de PORT_IN está activo, funcione de la manera descripta, pero si cualquiera de ellos se encuentra en estado activo (ej.: mientras un pulsador este accionado) el sentido de rotación sea inverso.
22) Modificar el problema anterior para que la rotación se alterne con cada pulsada (sin necesidad de mantener accionado el pulsador). Controlar si el programa responde adecuadamente a cada pulsada.
23) Realizar un programa que muestre inicialmente todos los leds asociados a PORT_OUT encendidos y a medida que se vayan pulsando y soltando cualquiera de los switch asociados a PORT_IN se vayan apagando leds de forma tal que los leds apagados vayan codificando en binario el número de pulsaciones realizadas con limite en 15. Al final de la cuenta, una nueva pulsada enciende todos los leds y así siguiendo. Controlar si el programa responde adecuadamente siempre.
24) El uso de pulsadores genera un problema conocido como "REBOTE", que se seguramente se manifestó en la ejecución de los programas anteriores. Solucionarlo considerando que solo se considerará como que un pulsador ha sido pulsado si su valor asociado asume el valor cero en dos lecturas consecutivas distanciadas en un tiempo T(mseg). Asumir T como el tiempo necesario para ejecutar aproximadamente 90.000 instrucciones.
25) Realizar un programa que mediante distintas configuraciones de leds activados indique cual ha sido el último switch pulsado.
26) Realizar un programa que genere un contador circular que muestre los distintos valores espaciados un tiempo T (necesario para ejecutar 300.000 instrucciones). El incremento del contador ( de a 1, de a 2 , de a 3 …..) se establece según cual haya sido el ultimo pulsador accionado conforme su posición en PORT_IN.
Soluciones propuestas
Solución ejercicio 2:
int main()
{
int x = 10;
int y = 20;
int z = 30;
int w;
w=y;
y=x;
x=z;
z=w;
return 0;
}
Solución ejercicio 6:
#include
int main()
{
int vleidos[10], valor;
for (int i=0; i (p)) & ~ (~0 > 1;
else { //el ultimo bit es 1
x = x >> 1;
x = x | 0x80;
}
}
return x;
}
int main()
{
x = 0xB7;
xx= rightRot(x,5);
return 0;
}
Solución ejercicio 17:
/* SOLUCION GENERAL */
unsigned char PORT_OUT; // esta variable representa las salidas
//prototipos
void inicializar();
void SetearSalidas(unsigned char work);
void main(void) {
unsigned char SALIDA=0b01010101; //logica positiva->posiciones pares en 1
Inicializar();
SetearSalidas(SALIDA);
// y supongo que el programa puede terminar
}
void Inicializar(){
return; // no hace falta inicializar nada
}
void SetearSalidas (unsigned char work){
PORT_OUT=work; // asumo que todos los bits de work tienen correspondencia con PORT_OUT
}
/* SOLUCION CONSIDERANDO UN MICROPROCESADOR DETERMINADO Y :
logica negativa (un pulsador accionado produce un "0"; un "0" en una salida prende el led)
solo hay 4 pulsadores disponibles
solo hay 4 leds disponibles
*/
#include "derivative.h" /* esto incluye la declaración de registros y periféricos correspondientes al MCU*/
/* prototipos */
void inicializar();
void SetearSalidas(unsigned char work);
void main(void) {
unsigned char SALIDA;
inicializar();
SALIDA=0b10101010; //ahora es al revés por la logica negativa
SetearSalidas(SALIDA);
for(;;) {
__RESET_WATCHDOG(); // por si el watchdog está activado
} /* el programa no debe terminar nunca */
}
void inicializar (){
PTFDD=0xFF; //el puerto F está conectado a los leds, así que lo defino de salida.
}
void SetearSalidas (unsigned char work){
/* Sólo los bits 0,1,4 y 5 tienen leds conectados */
PTFD_PTFD0=work & 0b00000001 ; // interesa primer bit de work
work=work>>1; // desplazo …
PTFD_PTFD1=work & 0b00000001; //… y comparo con lo mismo
work=work>>1;
PTFD_PTFD4=work & 0b00000001;
work=work>>1;
PTFD_PTFD5=work & 0b00000001;
}
Solución ejercicio 21:
/* SOLUCION GENERAL */
unsigned char PORT_IN;
unsigned char PORT_OUT;
/* prototipos */
void inicializar(void);
void SetearSalidas(unsigned char work);
unsigned char LeerEntradas (void);
void espera(long TiempoDeEspera);
void main(void) {
unsigned char ENTRADA;
unsigned char SALIDA;
inicializar();
SALIDA=0b00000001;
SetearSalidas(SALIDA);
for(;;) {
ENTRADA=LeerEntradas();
if(ENTRADA == 0){
SALIDA= SALIDA > 1 ;
if(SALIDA==0)SALIDA=128;
}
SetearSalidas(SALIDA);
espera(300000);
}
}
void inicializar (){
return; // nada que inicializar
}
void SetearSalidas (unsigned char work){
PORT_OUT= work;
}
unsigned char LeerEntradas (){
return PORT_IN;
}
void espera(long TiempoDeEspera){
long contador= TiempoDeEspera;
while(–contador){
}
}
/* SOLUCION CONSIDERANDO UN MICROPROCESADOR DETERMINADO Y :
logica negativa (un pulsador accionado produce un "0"; un "0" en una salida prende el led)
solo hay 4 pulsadores disponibles
solo hay 4 leds disponibles
*/
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
/* prototipos */
void inicializar();
void SetearSalidas(unsigned char work);
unsigned char LeerEntradas ();
void espera(int TiempoDeEspera);
void main(void) {
unsigned char ENTRADA;
unsigned char SALIDA;
inicializar();
SALIDA=0b11111011;
SetearSalidas(SALIDA);
for(;;) {
ENTRADA=LeerEntradas();
if(ENTRADA == 15){ //solo hay 4 pulsadores, con logica negativa
espera(300000);
SALIDA= SALIDA > 1 ;
SALIDA=SALIDA | 128;
if(SALIDA==255)SALIDA=247;
SetearSalidas(SALIDA);
__RESET_WATCHDOG();
}
__RESET_WATCHDOG();
} /* loop forever */
/* please make sure that you never leave main */
}
void inicializar (){
PTFDD=0xFF; //puerto F como salida
/* puerto G como entrada */
PTGD = (PTGD & (unsigned char)~0x2A) | (unsigned char)0x55;
// PTGPE PULL ENABLE REGISTER
/* PTGPE: PTGPE6=1,PTGPE5=1,PTGPE4=1,PTGPE3=1,PTGPE2=1,PTGPE1=1,PTGPE0=1 */
PTGPE |= (unsigned char)0x7F;
/* PTGDD: PTGDD6=0,PTGDD5=0,PTGDD4=0,PTGDD3=0,PTGDD2=0,PTGDD1=0,PTGDD0=0 */
PTGDD &= (unsigned char)~0x7F;
}
void SetearSalidas (unsigned char work){
PTFD_PTFD0=work & 0b00000001 ;
work=work>>1;
PTFD_PTFD1=work & 0b00000001;
work=work>>1;
PTFD_PTFD4=work & 0b00000001;
work=work>>1;
PTFD_PTFD5=work & 0b00000001;
}
unsigned char LeerEntradas (){
unsigned char work;
work=PTGD_PTGD0*1;
work= work + PTGD_PTGD1*2;
work= work + PTGD_PTGD2*4;
work= work + PTGD_PTGD3*8;
return work;
}
void espera(int TiempoDeEspera){
int contador= TiempoDeEspera;
while(–contador){
__RESET_WATCHDOG(); //por si el watchdog está activo
}
}
Solución ejercicio 23:
/* SOLUCION CONSIDERANDO UN MICROPROCESADOR DETERMINADO Y :
logica negativa (un pulsador accionado produce un "0"; un "0" en una salida prende el led)
solo hay 4 pulsadores disponibles
solo hay 4 leds disponibles
*/
#include "derivative.h" /* include peripheral declarations */
void inicializar();
void SetearSalidas(unsigned char work);
unsigned char LeerEntradas ();
void main(void) {
unsigned char ENTRADA;
unsigned char SALIDA;
unsigned char CantPulsos=0;
unsigned char Senal;
inicializar();
SALIDA=0b00000000;
SetearSalidas(SALIDA);
for(;;) {
ENTRADA=LeerEntradas();
if(ENTRADA == 15){
Senal=0;
}
else {
if(Senal==0){
CantPulsos++;
if(CantPulsos > 15)CantPulsos=0;
SALIDA=CantPulsos;
SetearSalidas(SALIDA);
Senal=1;
}
}
__RESET_WATCHDOG();
} /* loop forever */
/* please make sure that you never leave main */
}
void inicializar (){
PTFDD=0xFF;
KBIPE=0x00;
PTGD = (PTGD & (unsigned char)~0x2A) | (unsigned char)0x55;
// PTGPE PULL ENABLE REGISTER Pareceria ser que si no le pones un 1 no toma bien la lectura
/* PTGPE: PTGPE6=1,PTGPE5=1,PTGPE4=1,PTGPE3=1,PTGPE2=1,PTGPE1=1,PTGPE0=1 */
PTGPE |= (unsigned char)0x7F;
/* PTGDD: PTGDD6=0,PTGDD5=0,PTGDD4=0,PTGDD3=0,PTGDD2=0,PTGDD1=0,PTGDD0=0 */
PTGDD &= (unsigned char)~0x7F;
}
void SetearSalidas (unsigned char work){
PTFD_PTFD0=work & 0b00000001 ;
work=work>>1;
PTFD_PTFD1=work & 0b00000001;
work=work>>1;
PTFD_PTFD4=work & 0b00000001;
work=work>>1;
PTFD_PTFD5=work & 0b00000001;
}
unsigned char LeerEntradas (){
unsigned char work;
work=PTGD_PTGD0*1;
work= work + PTGD_PTGD1*2;
work= work + PTGD_PTGD2*4;
work= work + PTGD_PTGD3*8;
return work;
}
Solución ejercicio 24:
/* SOLUCION GENERAL aplicada al Ejercicio 22*/
unsigned char PORT_IN;
unsigned char PORT_OUT;
/* prototipos */
void inicializar(void);
void SetearSalidas(unsigned char work);
unsigned char LeerEntradas (void);
unsigned char LeerAntirebote(void);
void espera(long TiempoDeEspera);
void main(void) {
unsigned char SALIDA;
int direccion=0;
int cambio=0;
inicializar();
SALIDA=0b00000001;
SetearSalidas(SALIDA);
for(;;) {
if(LeerAntirebote()!=0){
if( cambio==0){
cambio=1;
direccion=~direccion;
}
}
else cambio=0;
//rotacion
if (direccion==0) {
SALIDA= SALIDA > 1 ;
if(SALIDA==0)SALIDA=128;
}
SetearSalidas(SALIDA);
espera(300000);
}
}
void inicializar (){
return; // nada que inicializar
}
void SetearSalidas (unsigned char work){
PORT_OUT= work;
}
unsigned char LeerEntradas (){
return PORT_IN;
}
unsigned char LeerAntirebote(){
unsigned char aux1,aux2;
aux1=LeerEntradas();
espera(90000);
aux2=LeerEntradas();
if (aux1==aux2)
return aux2;
else
return aux1;
}
void espera(long TiempoDeEspera){
long contador= TiempoDeEspera;
while(–contador){
}
}
Autor:
Iván José Pablo Turmero Astros