I hope this code should work on conveyorYep, you do.
#include <xc.h>
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define ENCODER RC0
#define SENSOR RC1
#define KICKER RD0
__bit gotIRQ; // signals main that an interrupt
void main(void)
{
unsigned int ShiftReg = 0; // Init to 0
INTCON = 0; // No interrupts
PORTC = 0b00000000; //Set all Pin to Low
TRISC0 = 1; // RC0 Eencoder Pin
TRISC1 = 1; // RC1 Sensor Pin
TRISD0 = 0; // RD0 Kicker Pin
//CCP1 MODULE INITIALIZATION
T1CON = 0b00000011 ; // 1:1 prescale, OSC disabled, Input Synchronized, External clock on T1CKI(RC0), Timer ON
CCP1CON = 0b00001011; // Compare mode using CCPR1H and CCPR1L as a 16 bit value
// 65536- 2165 = 63,371 is eual to 0xF78B
CCPR1H = 0xF7;
CCPR1L = 0x8B;
CCP1IF = 0;
INTCON = 0xc0; //Enabled Global interrupts & Peripherals interrupt
CCP1IE = 1; //Enabled CCP1 interrupt
while(1)
{
if (gotIRQ)
ShiftReg << 1; // shift the integer shift register one bit left. LSbit = 0 after shift
if (SENSOR == 1)
ShiftReg |= 0x0001; // bad object, put 1 in LSbit
if(ShiftReg & 0x0400) // and if the #10 bit after shift is '1', kick it
KICKER =~ KICKER ;
gotIRQ = 0; // acknowledge the interrupt
}
}
void __interrupt() IRQ(void){
// CCP1 Interrupt
if(CCP1IF == 1) // if the CCP1 Interrupt flag is set...
{
CCP1IF = 0;
gotIRQ = 1; // 'Signal' main that an interrupt happened
}
}
???KICKER=~ KICKER;
Right
KICKER = ~KICKER ;
Yes. You don’t want to toggle the kicker, you want to turn it on and off according to the bit in the shift register.Right KICKER = ~KICKER ;
Anything else
@JohnInTX There is air pusher rejection system as given in following videoYes. You don’t want to toggle the kicker, you want to turn it on and off according to the bit in the shift register.
I’m not where I can check the timer setup.
Good luck!
if(ShiftReg & 0x0400)
KICKER = -KICKER;
KICKER = (ShiftReg & 0x400);
You may have to implement a short delay if KICKER is true. Depends on the reject mechanism.I don’t intend to confuse matters, but you can simplify the code a bit. Instead of this:
You could simply write:Code:if(ShiftReg & 0x0400) KICKER = -KICKER;
This would ensure that KICKER is set properly for all iterations of the loop.Code:KICKER = (ShiftReg & 0x400);
#include <xc.h>
#define _XTAL_FREQ 20000000
#define ENCODER RC0
#define SENSOR RC1
#define KICKER RD0
// CONFIG
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
//END CONFIG
void UART_Init(void)
{
TXSTA = 0b00100100; // Transmit enabled = 1, BRGH=1 High speed
RCSTA = 0b10010000; // Serial Port, Continuous Receive enabled
SPBRG = 0x81; // baud rate 9600
}
void UART_TxChar(char ch)
{
while(TXIF==0); // Wait till the transmitter register becomes empty
TXIF=0; // Clear transmitter flag
TXREG=ch; // load the char to be transmitted into transmit reg
}
char UART_RxChar()
{
while(RCIF==0); // Wait till the data is received
RCIF=0; // Clear receiver flag
return(RCREG); // Return the received data to calling function
}
void main(void)
{
TRISC0 = 1; // RC0 Eencoder Pin
TRISC1 = 1; // RC1 Sensor Pin
TRISD0 = 0; // RD0 Kicker Pin
UART_Init;
while(1)
{
if (SENSOR == 1)
send_signal_to_PC;
}
}
@JohnInTX Does it make sense ?I show how to use printf with the USART in #32 and #34 here. You have to rename your low level read/write to the USART getch and putch and then it will work with the standard C conio.h library. There is also an excerpt from the XC8 manual that describes the function in detail.
https://forum.allaboutcircuits.com/threads/uart-register-configuration.158219/page-2#post-1376190
https://forum.allaboutcircuits.com/threads/uart-register-configuration.158219/page-2#post-1377037
#include <xc.h>
#include <stdio.h>
#include <conio.h>
#define _XTAL_FREQ 20000000
#define ENCODER RC0
#define SENSOR RC1
#define KICKER RD0
// CONFIG
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
//END CONFIG
void UART_Init(void)
{
TXSTA = 0b00100100; // Transmit enabled = 1, BRGH=1 High speed
RCSTA = 0b10010000; // Serial Port, Continuous Receive enabled
SPBRG = 0x81; // baud rate 9600
}
void putch(char data){
while(!TRMT);
TXREG = data;
}
unsigned char getch(){
while(!RCIF);
return RCREG;
}
void main(void)
{
TRISC0 = 1; // RC0 Eencoder Pin
TRISC1 = 1; // RC1 Sensor Pin
TRISD0 = 0; // RD0 Kicker Pin
UART_Init;
while(1)
{
if (SENSOR == 1)
{
printf("\rThe Sensor is: %d", SENSOR);
}
else
{
printf("\rThe Sensor is: %d", SENSOR);
}
}
}
I agree that writing full 8 bit values to the TRIS registers is optimal (at least with regard to code size) -- when possible, as in this case.Always use full bytes i.e. TRISC = 0bxxxxxxxx; That will avoid problems in the PIC hardware.
Wow. I stand (slightly) corrected.@joeyd999
I believe that is Microchip's recommendation as TRIS is subject to RMW corruption. Nevertheless, when you look at the Microchip forums, you can find examples of the XC8 compiler doing bit-wise writes and how it should be coded to avoid that.
The problem is apparently most common when using I2C:
https://www.microchip.com/forums/m1064930.aspx (XC8 bit-wise)
http://ww1.microchip.com/downloads/en/DeviceDoc/80131e.pdf (under the MSSP section, p.4)
MOVF TRISC, W ; Example for a 40-pin part such as the PIC16F877A
IORLW 0x18 ; Ensures <4:3> bits are ‘11’
ANDLW B’11111001’ ; Sets <2:1> as output, but will not alter other bits
; User can use their own logic here, such as IORLW, XORLW and ANDLW
MOVWF TRISC
@JohnInTXIO:
You should initialize the UART TX to an output 1 and RX to an input.
// bit0 Eencoder Pin input, bit1 Sensor Pin input, bit 6 TX Pin set as output, bit 7 RX Pin set as input
TRISC = 0b10000011;
How should i init UART ?That way if you have to re init the UART, you don't have transients on the lines.
Line 47 does not call UART_Init the way it is written.
That's what I am doing but it's under of while loop so it will repeatYou should only printf when the sensor changes. The way you have it, it will send the line over and over as long as the sensor bit is 1.
OK but it still writes and re-writes one of those messages continuously because you are looking at the static value of the sensor rather than detecting and responding to changes.That's what I am doing but it's under of while loop so it will repeat
That's how to do it. Now, init ALL the IO, even the pins you are not using.// bit0 Eencoder Pin input, bit1 Sensor Pin input, bit 6 TX Pin set as output, bit 7 RX Pin set as input
TRISC = 0b10000011;
I don't really know. I would always recommend 18F over 16F but I haven't used that particular part or evaluation board. The one on that board is 3.3Vmax, will that do? Note that there are many 18F's and 16F1xxx Enhanced Midrange that will drop into the same socket as your '877A. You can proceed now with the 877A then upgrade as your requirements become more apparent. As before, if you are looking to upgrade have at it but consider looking at some that have built-in quadrature encoder modules. A parametric search on Microchip.com will help you there. But in any case, you'll have to have a firm idea of the features/performance that your application requires and use those as a guide.I don't have pic18F series so I want to purchase this https://in.element14.com/microchip/ma180034/module-pic18f87j94-plug-in-80pin/dp/2313811
Will it be right to buy
@JohnInTX Back to the first topicOn another topic, the PC connection via UART is something new again.. It's pointless to code and debug something out of context only to find that all of your work comes to nothing when it won't integrate with the main project.
#include <xc.h>
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define ENCODER RC0
#define SENSOR RC1
#define KICKER RD0
__bit gotIRQ; // signals main that an interrupt
void main(void)
{
unsigned int ShiftReg = 0; // Init to 0
INTCON = 0; // No interrupts
TRISC = 0b00000011; // RC0 Eencoder Pin RC1 Sensor Pin
TRISD = ob11111110; // RD0 Kicker Pin
//CCP1 MODULE INITIALIZATION
T1CON = 0b00000011 ; // 1:1 prescale, OSC disabled, Input Synchronized, External clock on T1CKI(RC0), Timer ON
CCP1CON = 0b00001011; // Compare mode using CCPR1H and CCPR1L as a 16 bit value
// 65536- 2165 = 63,371 is eual to 0xF78B
CCPR1H = 0xF7;
CCPR1L = 0x8B;
CCP1IF = 0;
INTCON = 0xc0; //Enabled Global interrupts & Peripherals interrupt
CCP1IE = 1; //Enabled CCP1 interrupt
while(1)
{
if (gotIRQ)
ShiftReg << 1; // shift the integer shift register one bit left. LSbit = 0 after shift
if (SENSOR == 1)
ShiftReg |= 0x0001; // bad object, put 1 in LSbit
if(ShiftReg & 0x0400) // and if the #10 bit after shift is '1', kick it
KICKER = 1; // set output pulse high
__delay_ms(30); // Delay to see ouput ( inbuilt delay)
KICKER = 0; // set output pulse low
gotIRQ = 0; // acknowledge the interrupt
}
}
void __interrupt() IRQ(void){
// CCP1 Interrupt
if(CCP1IF == 1) // if the CCP1 Interrupt flag is set...
{
CCP1IF = 0;
gotIRQ = 1; // 'Signal' main that an interrupt happened
}
}
| Thread starter | Similar threads | Forum | Replies | Date |
|---|---|---|---|---|
| V | Hx711 with pic16f877A ..#2 | Microcontrollers | 1 | |
| M | Hx711 with pic16f877A | Microcontrollers | 29 | |
| M | Indicateur numérique de pesage | Microcontrollers | 4 | |
| B | PIC16F877A interface IR sensor to count object pass by. | Sensor Design & Implementation | 1 | |
| J | PIC16F877A for control mobile object tracking | Microcontrollers | 1 |