Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?
21/04/2015 #2881

Avatar de torres.electronico

Hola,no es problema del software... eso pasa cuando presionamos la tecla "insert" de nuestro teclado
Cuando te pase eso,tocas nuevamente esa tecla y volvera todo a la normalidad
21/04/2015 #2882


Muchas gracias por tan pronta respuesta.
23/04/2015 #2883


Hola. Buenos días. Estoy haciendo un programa sencillo de distintos menús en LCD con 1 solo pulsador,
ya que quiero ir avanzando con lo que he aprendido, pero veo que al compilarlo y probarlo, el LCD me muestra varios menús sin necesidad de un presionar el pulsador, está como loco.

Copio lo que llevo hasta ahora.
Código:
;*********************************************************************************************************;
                      
OSCCON=%01100110  ; Se utiliza para pic 16f88, Configura oscilador interno en 4MGH de frecuencia estable                                            

ANSEL=0           ; Se utiliza para pic 16f88, Todos los puertos configurados como digital y si los queremos analogos los = 1                     

;*******************************************************************************
DEFINE LCD_DREG PORTB  ; Indica que el Bus estará conectado en el Puerto B

DEFINE LCD_DBIT 4      ' Selección del Bit de inicio del puerto en el uC para el
                       ' bus de datos de la LCD
DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto B
DEFINE LCD_RSBIT 3     ' "RS" estará conectado en RB3
DEFINE LCD_EREG PORTB  ' Indica al uC que el pin "E" estará en el Puerto B
DEFINE LCD_EBIT 2      ' "E" estará conectado en RB2
Define Osc 4           ' Define el Oscilador para un Cristal
                       ' de 4 Mhz.

TRISA=%00111110
TRISB=%00000000


;************************* Pines de control ************************

Symbol enter = PORTA.1


;****************************** Declaración de variables******************************
B0      Var Byte
B1      Var Byte
B2      Var Byte

Dias  Var Byte
Tardes   var byte
Noches  var byte

cafe var byte
arroz var byte
jugo var byte

dato var byte
datod var byte
datoa var byte
datoc var byte

Dato = 0
datod = 0
datoa = 0
datoc = 0

LCDOut $fe, 1 ' Limpia la pantalla



Inicio:

LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Bienvenidos"
LCDOut $fe,$C0, "Welcome"

clear
     

;Menus:


   For B0 = 1 To 200
   if enter=0 and dato = 0 then gosub suma
   Next
   gosub Hola1
   
   For B1 = 1 To 200
   if enter=0 and dato = 1 then gosub suma
   next 
   gosub Hola2    
    
   For B2 = 1 To 200
   if enter=0 and dato = 2 then gosub suma
   next
   gosub Hola3 

;goto Menus
goto Inicio
    
Hola1:

for Dias = 1 to 30
lcdout $fe,1    
lcdout $fe,$80,"Buenos"
lcdout $fe,$c0,"Dias"
   pause 100
   NEXT Dias

lcdout $fe,1    
lcdout $fe,$80,"Como"
lcdout $fe,$c0,"Estas"   
pause 300  

if enter = 0 then gosub desayuno

return    


    
Hola2:

for Tardes = 1 to 30
lcdout $fe,1    
lcdout $fe,$80,"Buenas"
lcdout $fe,$c0,"Tardes"
   pause 100
NEXT Tardes

lcdout $fe,1    
lcdout $fe,$80,"Veo que"
lcdout $fe,$c0,"Estas bien"
pause 300 

if enter = 0 then gosub almuerzo

RETURN 


Hola3:

for Noches = 1 to 30
lcdout $fe,1    
lcdout $fe,$c80, "Buenas"
lcdout $fe,$c0,"Noches"
  pause 100
  NEXT Noches
  
lcdout $fe,1    
lcdout $fe,$80,"Que pases"
lcdout $fe,$c0,"Bien"
pause 300   

if enter = 0 then gosub cena

RETURN    

desayuno:

for cafe = 1 to 30
lcdout $fe,1    
lcdout $fe,$c80, "Elija 1 opcion"
lcdout $fe,$c0,"de desayuno"
  pause 100
  NEXT cafe  
  
lcdout $fe,1    
lcdout $fe,$80,"1- Americano"
lcdout $fe,$c0,"2- Nativo"
pause 300   

if enter = 0 and datod = 0  then gosub sumad
lcdout $fe,1    
lcdout $fe,$80,"1- Americano"
pause 300

if enter = 0 and datod = 1  then gosub sumad
lcdout $fe,1 
lcdout $fe,$c0,"2- Nativo"
pause 300

lcdout $fe,1    
lcdout $fe,$80,"Gracias por"
lcdout $fe,$c0,"su eleccion"
pause 300  


RETURN   
  
  
almuerzo:

for arroz = 1 to 30
lcdout $fe,1    
lcdout $fe,$c80, "Elija 1 opcion"
lcdout $fe,$c0,"de almuerzo"
  pause 100
  NEXT arroz  
  
lcdout $fe,1    
lcdout $fe,$80,"1- Guisado"
lcdout $fe,$c0,"2- Sopa"
pause 300   

if enter = 0 and datoa = 0  then gosub sumaa
lcdout $fe,1    
lcdout $fe,$80,"1- Guisado"
pause 300

if enter = 0 and datoa = 1  then gosub sumaa
lcdout $fe,1 
lcdout $fe,$c0,"2- Sopa"
pause 300

lcdout $fe,1    
lcdout $fe,$80,"Gracias por"
lcdout $fe,$c0,"su eleccion"
pause 300  


RETURN        



cena:

for jugo = 1 to 30
lcdout $fe,1    
lcdout $fe,$c80, "Elija 1 opcion"
lcdout $fe,$c0,"de almuerzo"
  pause 100
  NEXT jugo  
  
lcdout $fe,1    
lcdout $fe,$80,"1- Asado"
lcdout $fe,$c0,"2- Pizza"
pause 300   

if enter = 0 and datoc = 0  then gosub sumac
lcdout $fe,1    
lcdout $fe,$80,"1- Asado"
pause 300

if enter = 0 and datoc = 1  then gosub sumac
lcdout $fe,1 
lcdout $fe,$c0,"2- Pizza"
pause 300

lcdout $fe,1    
lcdout $fe,$80,"Gracias por"
lcdout $fe,$c0,"su eleccion"
pause 300  


RETURN        
    


Suma:
Dato = Dato + 1            ' Incrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el incremento de la variable sea muy acelerado
                           ' mientras el pulsador "enter" esté presionado.
Return                     ' Retorna una línea después del llamado "gosub Suma".


Sumad:
datod = datod + 1            ' Incrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el incremento de la variable sea muy acelerado
                           ' mientras el pulsador "enter" esté presionado.
Return                     ' Retorna una línea después del llamado "gosub Suma".



Sumaa:
datoa = datoa + 1            ' Incrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el incremento de la variable sea muy acelerado
                           ' mientras el pulsador "enter" esté presionado.
Return                     ' Retorna una línea después del llamado "gosub Suma".



Sumac:
datoc = datoc + 1            ' Incrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el incremento de la variable sea muy acelerado
                           ' mientras el pulsador "enter" esté presionado.
Return                     ' Retorna una línea después del llamado "gosub Suma".
23/04/2015 #2884


Hola. Deberías empaquetar todo (Programa, archivo compilado, simulación) en un archivo comprimido y subirlo porque ya de entrada, si no pones resistencia de Pull-UP en PortA.1, va a ir a "sumar" ya que Dato=0
No seguí analizando la lógica del programa.
Saludos.

Ric.
23/04/2015 #2885


Hola, adjunto el archivo de simulación y los demas archivos, asi como esta simulado lo tengo montado en protoboard. El oscilador del pic 16f88, esta configurado internamente a 4 Mh, utilizo una resistencia pull-up en el puerto A.
Archivos Adjuntos
Tipo de Archivo: rar Menu lcd puldador.rar (32,6 KB (Kilobytes), 48 visitas)
24/04/2015 #2886


La lógica del programa no me "cierra", el bucle principal esta permanentemente y de forma innecesaria, imprimiendo en el display y limpiándolo cuando esta a la espera, cuando pulsas "enter", se desencadenan una serie de mensajes, sin ningún tope,etc, etc....te sugiero que empieces por volcar tú idea en un programa corto de pocas lineas y ver como funciona, a este le agregas después otras opciones y pruebas y así sucesivamente hasta que funcione como tú esperas.
No se que quieres hacer con un solo botón/pulsador pero ten en cuenta que cuando mas simple es el hardware, mas complejo es la programación y mas espacio ocupa el software. Cuando usas diferentes freses a mostrar te quedas sin espacio enseguida.
Revisa la instrucción "Button" de la ayuda del PBP, que te puede servir para lo que quieras hacer.
Saludos.

Ric.
27/04/2015 #2887


Hola buenas noches, hice unos cambios y logré algo de avance pero me toca dejar undido el pulsador para que me responda a los demas menus secundarios; intentaré con la instrucción Button, gracias de todas maneras por su colaboración.

Disculpen aqui adjunto el archivo modificado. gracias
Archivos Adjuntos
Tipo de Archivo: rar Menu lcd puldador.rar (38,5 KB (Kilobytes), 29 visitas)
30/04/2015 #2888


Hola buenos dias, He estado leyendo sobre el Pic 18f2550 de 28 pines y lo que he logrado entender acerca de la conversión de los pines de analogo a digital en los 4 puertos que dispone utilizandolos con PBP y MCS; es que solo es posible en los siguientes pines:

Entrada y salida digital
Puerto A: RA.0-RA.1-RA.2-RA.3-RA.5
Puerto B: RB.0-RB.1-RB.2-RB.3-RB.4-RB.5-RB.6-RB.7
Puerto C: RC.0-RC.1-RC.2-RC.6-RC.7

Solo salida digital
Puerto A: RA.4

Entiendo que CMCOM = 7 , Desactiva los comparadores analogicos, pero no se si de los 3 puertos a la vez; como tambien que ADCON1 = 0F configura el Puerto A con ADC como digital y ADCON1 = 0E configura el Puerto B con ADC como digital; Pero entonces como configuro el puerto C? o estoy totalmente errado en todo lo que acabo de escribir? Muchas gracias.
30/04/2015 #2889
Moderador

Avatar de D@rkbytes

En parte estás errado. Por eso siempre les digo que lean la hoja de datos.

En la sección ADCON0 se muestra la configuración de bits para la selección de los canales. ADCON0.JPG

ADCON0 funciona conjuntamente con el registro ADCON1 y muestra ésta tabla: ADCON1.JPG

Estableciendo adecuadamente los bits de los registros ADCON0 y ADCON1 se selecciona el canal o canales ADC que estarán activos.
En esos mismos registros también se configura el modo de operación.

El registro CMCON no involucra a todos los puertos porque no todos tienen comparadores análogos.
Éstos únicamente se encuentran en el puerto A y esto también lo puedes ver en la hoja de datos. (Sección: Comparator Module)

El puerto C no tiene conversores AD y tampoco tiene comparadores análogos, éste tiene otro tipo de funciones y su configuración depende de los módulos que quieras usar.
Si lo piensas utilizar como un puerto estándar Digital I/O, no hay mucho que configurar.
Pero recuerda que el módulo del Bus USB forma parte del puerto C.
30/04/2015 #2890


Muchas gracias por tan pronta respuesta; leyendo nuevamente y comparando con lo que escribiste comprendí un poco mas, realicé una pequeña prueba y funcionó.

4 pulsadores N/A en el Puerto A (0,1,2,3) y un diodo led en el Puerto C.7

OSCCON=%01100110 ; Configura oscilador interno en 4MGH de frecuencia estable
CMCON = 7 ; Desactiva los comparadores analogicos de todos los pines del puerto A .

ADCON0 = 63 ; ADCON0 = 3F
ADCON1 = 15 ; ADCON1 = F

Define Osc 4 ; Define el Oscilador de 4 Mhz.

TRISA = %111111 ; Configura el Puerto A como Entrada.
TRISC = %00000000 ; Configura el Puerto C como Salida.

PORTC = $00 ; Inicializa el puerto C.

Inicio:
If PORTA.0 = 0 Then PORTC.7 = 1 ; Pregunta si RA0 = 0, entonces RC.7 = 1
If PORTA.1 = 0 Then PORTC.7 = 1 ; Pregunta si RA1 = 0, entonces RC.7 = 1
If PORTA.2 = 0 Then PORTC.7 = 1 ; Pregunta si RA2 = 0, entonces RC.7 = 1
If PORTA.3 = 0 Then PORTC.7 = 1 ; Pregunta si RA0 = 0, entonces RC.7 = 1

Pause 500 ; Hace una pausa de 1 segundo (500 ms)

Low PORTC.7 ; Apaga el Led
Pause 500 ; Hace una pausa de 1/2 segundo (500 ms)
GoTo inicio ; Salta a la etiqueta "Inicio"
End
06/05/2015 #2891

Avatar de juancaca

Hola buenas noches, bueno en este momento me encuentro ensayando con las matrices de led, hasta ahora se mostrar una letra, lo que me gustaria hacer, es hacer que se desplace hacia la izquierda, mirando codigos que han subido en el foro no logro entender como hacen para que se desplace el texto utilizando el IC 74hc164, me podria hacer el favor de explicarme como hacerlo con PBP.

Codial saludo.
07/05/2015 #2892


Hola. Buenos días. He estado practicando con el PIC18F2550 utilizando LED y buzzer en pequeños programas y me han funcionado.
No he tenido la necesidad de colocar los fuses en MCS ya que en el software del programador los coloco,
pero ahora empecé a utilizar un LCD de 16x2 con el PIC18F2550 tomando como ejemplo del tutorial de PBP sin tener buenos resultados.

En el LCD me salen varios caracteres, menos los que deben salir y en el proteus se muestra pero no como lo que debería salir.
Adjunto fotos, archivos de simulación y demás.

Agradecería mucho que me indicaran en que me tengo que corregir. Muchas gracias.

---------- Actualizado después de 2 horas ----------

Hola compañeros. Me autocorrijo en lo siguiente:

If P1 = 1 Then Call Mensaje1 ' Pregunta si RA0 = 1
If P2 = 1 Then Call Mensaje2 ' Pregunta si RA1 = 1

Corrección: P1 y P2 se deben igualar a 0

If P1 = 0 Then Call Mensaje1 ' Pregunta si RA0 = 1
If P2 = 0 Then Call Mensaje2 ' Pregunta si RA1 = 1

Y en el " Menu #1 " y " Menu #2 ", se deben llenar los 16 caracteres con espacios de lado y lado dentro de las comillas, para que se cubra totalmente el renglón superior y no aparezca parte del mensaje anterior.

Muchas gracias de todas maneras.
Archivos Adjuntos
Tipo de Archivo: rar LCD PIC18F2550.rar (461,0 KB (Kilobytes), 33 visitas)
07/05/2015 #2893

Avatar de ferdy575

Hola a todos.
Vengo por aquí a molestar, a ver sí me pueden ayudar con un trabajito.
Se trata de hacer un control para un motor DC.
La idea es poner un número determinado de revoluciones y que si por motivo de trabajo las revoluciones se bajan, el pic aumente el duty del pwm para que el motor se recupere.

La verdad no sé como hacer la comparación de las variables, para que sí una disminuye, la otra aumente y me cambie el duty del pwm.

Aquí les subo los archivos para que vean de que hablo.
Archivos Adjuntos
Tipo de Archivo: rar gobernador.rar (2,91 MB (Megabytes), 26 visitas)
09/05/2015 #2894


Hola buenas tardes, estoy realizando ejercicios con el pic 18f2550 y queria saber si es posible que con un pulsador se borre o cambie un dato ya programado en la eeprom de este pic, adjunto un sencillo ejercicio que hice, donde se simula el dato y la direccion donde fue guardado pero todavia no lo he podido cambiar con el pulsador. gracias.
Archivos Adjuntos
Tipo de Archivo: rar Memoria EEPROM.rar (31,4 KB (Kilobytes), 16 visitas)
09/05/2015 #2895
Moderador

Avatar de D@rkbytes

  1. Si estás utilizando un cristal de 4 MHz, entonces la palabra de configuración no es correcta.
  2. Realizas comparaciones de estado de pines y variables, pero las variables nunca las inicializas.
  3. Haces llamadas a subrutinas pero usas Return, en ese caso debes usar GoSub [Etiqueta]
Puedes ir a subrutinas usando GoTo y retornar nuevamente con GoTo a una etiqueta.

En PICBasic se puede hacer así:
If Sentencia Then Mi_Rutina

O así:
If Sentencia Then GoTo Mi_Rutina

Y de la rutina regresas nuevamente con un GoTo: GoTo [Etiqueta]

Pero no debes llamar a una subrutina con Then Mi_Rutina, porque equivale a usar un GoTo
Cuando haces eso se produce un desborde de pila llevando el programa al vector de reset. (ORG 0)

Es decir, el programa se reinicia desde el principio por no tener un punto de referencia a donde regresar.

Entonces como mencioné, si piensas regresar con Return, debes llamar a la subrutina con GoSub o Call
09/05/2015 #2896


D@rkbytes dijo: Ver Mensaje
  1. Si estás utilizando un cristal de 4 MHz, entonces la palabra de configuración no es correcta.
  2. Realizas comparaciones de estado de pines y variables, pero las variables nunca las inicializas.
  3. Haces llamadas a subrutinas pero usas Return, en ese caso debes usar GoSub [Etiqueta]
Puedes ir a subrutinas usando GoTo y retornar nuevamente con GoTo a una etiqueta.

En PICBasic se puede hacer así:
If Sentencia Then Mi_Rutina

O así:
If Sentencia Then GoTo Mi_Rutina

Y de la rutina regresas nuevamente con un GoTo: GoTo [Etiqueta]

Pero no debes llamar a una subrutina con Then Mi_Rutina, porque equivale a usar un GoTo
Cuando haces eso se produce un desborde de pila llevando el programa al vector de reset. (ORG 0)

Es decir, el programa se reinicia desde el principio por no tener un punto de referencia a donde regresar.

Entonces como mencioné, si piensas regresar con Return, debes llamar a la subrutina con GoSub o Call
Hola buenas noches, muchas gracias por tan pronta respuesta; inmediatamente corregiré lo de la inicializacion de las varibles y para llamar a las subrutinas utilizaré CALL, La verdad es que apenas con este pic 18f2550 que me regalaron, es que estoy colocando los fuses en el MCS ya que siempre con los otros pic mas pequeños utilizaba los fuses del programador, te agradecería enormemente si me indicaras cual es la palabra correcta para utilzar como oscilador externo un cristal de 4MHZ sin utilizar el USB en este pic 18f2550 y si no fuera molestia facilitarme uno o dos ejemplos en PBP donde con un pulsador pueda borrar y o cambiar un dato grabado anteriormente en una y o varias direcciones de la eeprom de este pic. Muy agradecido por tu atención prestada y tu sabio conocimiento.
10/05/2015 #2897
Moderador

Avatar de D@rkbytes

La palabra de configuración para un cristal de 4 MHz sin usar el módulo USB, es esta:
Código:
Asm
    Config FOSC = XT_XT, WDT = OFF, PWRT = ON, LVP = OFF
    Config USBDIV = 1, PLLDIV = 1
EndAsm
Para que funcione al compilar, se debe editar el archivo 18F2550.INC, comentando los fuses que vienen por defecto.
Esto ya se ha tratado aquí en el Foro: Bits de Configuracion PIC 18F4550/PicBasic Pro
El ejemplo citado en ese post también aplica para el PIC18F2550

Sobre los ejemplos de lectura y escritura de la EEPROM interna, no hay mucho que decir.
Lee sobre las instrucciones; Write y Read. Lo demás es cuestión de aplicarlas en tu programa.

Para obtener ayuda sobre las instrucciones, sitúa el cursor sobre la instrucción y presiona la tecla F1.
10/05/2015 #2898


D@rkbytes dijo: Ver Mensaje
La palabra de configuración para un cristal de 4 MHz sin usar el módulo USB, es esta:
Código:
Asm
    Config FOSC = XT_XT, WDT = OFF, PWRT = ON, LVP = OFF
    Config USBDIV = 1, PLLDIV = 1
EndAsm
Para que funcione al compilar, se debe editar el archivo 18F2550.INC, comentando los fuses que vienen por defecto.
Esto ya se ha tratado aquí en el Foro: Bits de Configuracion PIC 18F4550/PicBasic Pro
El ejemplo citado en ese post también aplica para el PIC18F2550

Sobre los ejemplos de lectura y escritura de la EEPROM interna, no hay mucho que decir.
Lee sobre las instrucciones; Write y Read. Lo demás es cuestión de aplicarlas en tu programa.

Para obtener ayuda sobre las instrucciones, sitúa el cursor sobre la instrucción y presiona la tecla F1.
Buenos dias, te adjunto el archivo mejorado con algunas modificaciones; ya no me muestra errores; los fuses los cambié como me indicaste, pero editados de forma diferente ya que al colocarlos igual como los mostraste, me salian errores, escucho tus sujerencias de como quedó con la mejora que le hice; todavia estoy investigando como con un 3er pulsador poder cambiar o borrar 1, 2 o los 3 datos grabados anteriormente en las posiciones de memoria $00, $01, $02 de la eeprom del pic 185f2550. Muy agradecido por tu atención y colaboración al desarrollo del conocimiento de estos temas.
Archivos Adjuntos
Tipo de Archivo: rar EEPROM MEJORADO.rar (33,6 KB (Kilobytes), 17 visitas)
10/05/2015 #2899
Moderador

Avatar de D@rkbytes

jesusmolo dijo: Ver Mensaje
Los fuses los cambié como me indicaste, pero editados de forma diferente, ya que al colocarlos igual como los mostraste, me salían errores.
Esa no es la forma correcta de escribir la palabra de configuración. No tiene la sintaxis que requiere MPASWIN.
La forma correcta es como te mencioné, y los errores se deben a que no lo estás haciendo como lo explico en el ejemplo del enlace que coloqué.

De la forma en como estás escribiendo la palabra de configuración no la toma en cuenta el compilador.

Si abres el archivo hexadecimal que se genera al compilar, verás que esos fuses no los toma en cuenta.
El archivo ejecutable sigue manteniendo los fuses por defecto del archivo 18F2550.INC



Escribiendo la palabra de configuración correctamente, así deben quedar.


Aquí el archivo ya se ha compilado con los fuses requeridos.

Lee con atención el ejemplo del enlace que mencioné anteriormente para que lo entiendas bien.

Suerte.
Imágenes Adjuntas
Tipo de Archivo: jpg Fuses Correctos.jpg (93,7 KB (Kilobytes), 140 visitas)
Tipo de Archivo: jpg Fuses Incorrectos.jpg (45,8 KB (Kilobytes), 139 visitas)
11/05/2015 #2900


Buenos días. Te cuento que no comprendía, por que no había leído bien, debido a que me confié por tener el archivo.INC actualizado; hasta que con el 1er ejemplo me di cuenta que el secreto esta en comentar las 5 palabras de configuración en el archivo.INC y listo, el MCS compilo sin errores y para verificar utilicé el winpic para comparar con tu imagen siendo las 2 iguales. Muchas gracias nuevamente.

---------- Actualizado después de 2 horas ----------


Hola, buenos días. Te comento que en proteus me funcionó perfectamente, pero al montarlo físicamente en lcd no muestra nada; lo raro es que al volver a su estado inicial el archivo.INC y colocar los antiguos fuses corre a las mil maravillas y el lcd muestra todo.
La verdad no entiendo porque pasa esto. ¿Por qué sucederá esto? En el proteus funciona con el archivo .INC original y modificado, pero en la realidad con el circuito físico montado sólo funciona con el archivo.INC original y los fuses que te envié inicialmente.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.