Atmega 32, Program to drive motor , How to take input integer from user - embedded

I am trying to write a simple program to take input from user by hterm, when User enters "motor" & "25" the motor will rotate in 25 clockwise and 25 anticlockwise direction
//Define clock-speed and include necessary headers
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include <util/delay.h>
#include <ctype.h>
#define F_CPU 16000000UL
#define BAUD 9600UL
char cmd[40];
void uart_init(void) // initializing UART
{
UBRRH = 0;
UBRRL = ((F_CPU+BAUD*8)/(BAUD*16)-1);
UCSRC |= 0x86; // 8N1 Data
UCSRB = 0x18; // Receiving and Transmitting
}
int uart_putch(char ch, FILE *stream) // Function for sending Data to PC
{
if (ch == '\n')
uart_putch('\r', stream);
while (!(UCSRA & (1<<UDRE)));
UDR=ch;
return 0;
}
int uart_getch(FILE *stream) // Function for receiving Data from PC
{
unsigned char ch; while (!(UCSRA & (1<<RXC)));
ch=UDR;
uart_putch(ch,stream); // Echo the output back to the terminal
return (tolower(ch));
}
FILE uart_str = FDEV_SETUP_STREAM(uart_putch, uart_getch, _FDEV_SETUP_RW); // Important, not deleting
void loeschen() // Delete the String
{
int strnglen = 0;
while (strnglen < 41 && cmd[strnglen] != 0)
{
cmd[strnglen]= 0;
strnglen++;
}
}
// Define the stepping angle
// Note: Divide by 2 if you are doing half-stepping. for filter test 1.8 defult
#define MIN_STEP 1.8
/* Define an array containing values to be sent at the required Port - for Full-stepping
<first four bits> - <last four bits> = <decimal equivalent>
00000001 = 1 ; 01000000 = 4
00000100 = 4 ; 00010000 = 16
00000010 = 2 ; 00001000 = 8
00001000 = 8 ; 00100000 = 32
*/
unsigned short control_array_full[4] = {4,16,8,32};
/* Define an array containing values to be sent at the required Port - for Half-stepping
<first four bits> - <last four bits> = <decimal equivalent>
0000-1001 = 8 + 1 = 9 ; 0010-0100 = 32 + 4 =36
0000-0001 = 1 ; 0000-0100 = 4
0000-0101 = 4 + 1 = 5 ; 00010100 = 16 + 4 = 20
00000100 = 4 ; 00010000 = 16
00000110 = 4 + 2 = 6 ; 00011000 = 16+8=24
0000-0010 = ; 00-001000 = 8
0000-1010 = 8 + 2 = 10 ; 00-101000 = 40
0000-1000 = 8 ; 00-100000 = 32
*/
unsigned short control_array_half[8] = {36,4,20,16,24,8,40,32};
// Adjust this delay to control effective RPM
// Do not make it very small as rotor will not be able to move so fast
// Currently set at 100ms
void delay()
{
_delay_ms(100);
}
void move_clockwise(unsigned short revolutions){
int i=0;
for (i=0; i < (revolutions* 360 /MIN_STEP) ; i++)
{
//Note: Take modulo (%) with 8 when half-stepping and change array too
PORTD = control_array_half[i % 4];
delay();
}
}
void move_anticlockwise(unsigned short revolutions){
int i;
for (i = (revolutions* 360 /MIN_STEP); i > 0 ; i--){
//Note: Take modulo (%) with 8 when half-stepping and change array too
PORTD = control_array_half[i % 4];
delay();
}
}
int main()
{
// Enter infinte loop
// Make changes here to suit your requirements
uart_init(); // initializing UART
stdout = stdin = &uart_str; // Necessary to compare whole Strings
while(1){
scanf("%s",&cmd); // Read String from Data Register
printf ("Please enter number of motor rotation for clockwise and anticlockwise");
items_read = scanf ("%d", &numbers[i]); // Read integer for motor revolution
if(strcmp(cmd, "motor") == 0)
{
DDRD = 0b00111110; //Set PORTD 4 bits for output
//Enter number of revolutions required in brackets
move_clockwise(items_read);
move_anticlockwise(items_read);
}
DDRD = 0b00000000;
}
loeschen();
}
Now, The problem is that when I will delete these lines from main()
items_read = scanf ("%d", &numbers[i]);
scanf ("%d",&i);
& make items_read in move_clockwise(items_read); as:
move_clockwise(25);
move_anticlockwise(25);
Then when user enters "motor" then motor is running move_clockwise(25); but move_anticlockwise(25); is not running, what I would like is to take both "motor", number for clockwise and number for anticlockwise....
I would really appreciate if anyone can help me with this!
Thanks in advance!

First, in my opinion you're only clearing "cmd" in loeschen(), but you never assining any value.
Second "cmd" is NOT any type of UART dataregister.
DDRD is DataDirectionRegister D, that means you can set some pin to input or output mode.
Use PORTD to set a pin high or low, in example PORTD |= 1<<PD0; to set Port D Pin 0 to high.
I guess you prefer german documentation, because you named one function "loeschen()" ;-), so why don't you visit mikrocontroller.net AVR GCC Tutorial (UART)?
If you like more technic detailed youtube-stuff, et voila: Introduction to UART
RXT (ATMEGA16) - for example:
//////////////////////////////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////////////////////////////
#define BAUD 9600UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Baud to high
#endif
#define UART_MAX_STRING_LENGHT 20 // Max lenght
//////////////////////////////////////////////////////////////////////////
// UART-Receive-Variables
//////////////////////////////////////////////////////////////////////////
volatile uint8_t uart_str_complete = 0; // FLAG - String received
volatile uint8_t uart_str_count = 0; // Current position
volatile char uart_string[UART_MAX_STRING_LENGHT + 1] = ""; // received string
//////////////////////////////////////////////////////////////////////////
// ISR-UART
//////////////////////////////////////////////////////////////////////////
ISR(USART_RXC_vect)
{
unsigned char nextChar;
nextChar = UDR; // read data from buffer
if(uart_str_complete == 0) // UART-String is currently usen
{
if(nextChar != '\n' && nextChar != '\r' && uart_str_count < UART_MAX_STRING_LENGHT)
{
uart_string[uart_str_count] = nextChar;
uart_str_count++;
}
else
{
uart_string[uart_str_count] = '\0';
uart_str_count = 0;
uart_str_complete = 1;
}
}
}
//////////////////////////////////////////////////////////////////////////
// Init UART
//////////////////////////////////////////////////////////////////////////
void Init_UART_Async()
{
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRB |= (1<<TXEN); // UART TX high
UCSRB |= (1<<RXEN); // UART RX high
UCSRB |= (1<<RXCIE); // UART RX Interrupt enable
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
sei(); // Enable interrups
}
//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
int main(void)
{
Init_UART_Async();
while(1)
{
HandleCommunication(); // <-- Handle your communication ;-)
// and to some other cool stuff here
}
}
//////////////////////////////////////////////////////////////////////////
// Handle Communication
//////////////////////////////////////////////////////////////////////////
void HandleCommunication()
{
if(uart_str_complete == 1)
{
strcpy(received_string, uart_string); // copy received string
strcpy(uart_string, ""); // empty uart-string
uart_str_complete = 0; // set flag to 0
// handle your communication
}
}
After understanding how UART is working, you should check your codeparts
like "scanf("%s",&cmd);" in an console-application - that's easier to find some errors.
I hope this helps you a little, but I guess the best solution is when you're knowing what you're doing.
-Crazy

Related

Do DLLs have a lower priority that may affect ethernet functionality? Experiencing TCP retransmissions

I have some modbus ethernet tcp communications that I'm attempting to do in a DLL. I get numerous TCP Retransmissions from the target device, as seen in WireShark.
(In this image, 192.168.1.5 is the Modbus device. 192.168.1.72 is the computer)
However, when the same code is inserted directly into an application, there are no communication errors.
I'm wondering if DLLs have some sort of lower priority that can cause slower communications, or if anyone may have any insight as to why this code would run without TCP issue in an application, but not in a DLL.
Here is the dll header:
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
typedef void *eioTHandle;
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int __stdcall eioConnect( unsigned short ModelId, char *Ip, eioTHandle *Handle );
#ifdef __cplusplus
}
#endif
#endif
And here is the source file:
#include "main.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdint.h>
#define EIO500_S 0
#define EIO500_MS 1000
#define eioERROR -1
#define eioSUCCESS 0
static uint8_t m_UnitId = 0xff;
static SOCKET m_Sock;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved )
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
int __stdcall eioConnect( unsigned short ModelId, char *Ip, eioTHandle *Handle )
{
WSADATA Wsa;
struct sockaddr_in Server;
int Result;
char Buffer[256];
char InBuffer[256];
// CONNECTION --------------------------------------------------------------
if (WSAStartup(MAKEWORD(2,2), &Wsa) != 0)
{
return eioERROR;
}
m_Sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_Sock == INVALID_SOCKET)
{
WSACleanup();
return eioERROR;
}
Server.sin_addr.s_addr = inet_addr(Ip);
Server.sin_family = AF_INET;
Server.sin_port = htons(502);
if (connect(m_Sock, (struct sockaddr *)&Server, sizeof(Server))
== SOCKET_ERROR)
{
closesocket(m_Sock);
m_Sock = INVALID_SOCKET;
WSACleanup();
return eioERROR;
}
// -------------------------------------------------------------------------
for (int Ctr = 0; Ctr < 50000; Ctr++)
{
// SEND COMMAND --------------------------------------------------------
// 5 bytes in a Send Read Multiple Coils command.
int NumBytes = 5;
Buffer[0] = 0;
Buffer[1] = 0;
Buffer[2] = 0;
Buffer[3] = 0;
Buffer[4] = 0;
Buffer[5] = NumBytes + 1; // 1 for unit id.
Buffer[6] = m_UnitId;
// 0 = Function code.
Buffer[7] = 0x01;
// 1+2 = Address.
Buffer[8] = 0;
Buffer[9] = 8;
// 3+4 = Number of bits to read.
Buffer[10] = 0;
Buffer[11] = 8;
if (send(m_Sock, Buffer, NumBytes + 7, 0) == SOCKET_ERROR)
{
continue;
}
// ---------------------------------------------------------------------
// WAIT FOR RECEIVE ----------------------------------------------------
WSAEVENT RecvEvent;
int Ret;
RecvEvent = WSACreateEvent();
WSAEventSelect( m_Sock, RecvEvent, FD_READ );
Ret = WSAWaitForMultipleEvents(1, &RecvEvent, TRUE, 1000, FALSE);
WSAResetEvent(RecvEvent);
if (Ret == WSA_WAIT_TIMEOUT)
continue;
// -------------------------------------------------------------------------
// Check for any reply.
recv(m_Sock, InBuffer, 256, 0);
}
// DISCONNECT --------------------------------------------------------------
Result = shutdown(m_Sock, SD_SEND);
if (Result == SOCKET_ERROR)
{
closesocket(m_Sock);
WSACleanup();
m_Sock = INVALID_SOCKET;
return eioERROR;
}
// Receive until the peer closes the connection.
while (recv(m_Sock, Buffer, 256, 0) > 0);
closesocket(m_Sock);
WSACleanup();
m_Sock = INVALID_SOCKET;
// ------------------------------------------------------------------------
return eioSUCCESS;
}
I've simplified the code as much as possible. The communication is in a loop for testing. The original application would poll this data from the device.
No. From the network's perspective there's no difference in TCP segments sent some way or other. There may be a protocol prioritation though (QoS) that may cause packet drops when links are saturated.
A more likely cause could be a problem with the checksums: invalid checksums cause packet drops which in turn cause retransmissions. Possibly the API works slightly different when called from a DLL, so the checksums are calculated (correctly).

Interrupt Handling 18F4550 PIC

I'm trying to get myself familiar with Interrupts when it comes to the 18F4550 PIC. At this point I've written a software that would light up an LED whenever the INT0 raises a flag.
My code states that every 500 ms, INT0 will raise a flag and "is supposed to" jump into an ISR and fire up a LED all while "transferring dummy data between Port C and Port D"
I've tried debugging, but once the debugger gets to the code that sets the INT0 flag to 1, the debugger says "No source code lines were found at current PC".
Here's the code below. Any kind of help is greatly appreciated. Thanks a lot!
Please note that I am using MPLAB X and a PicKit3
#include <xc.h>
#include <p18f4450.h>
#include <stdlib.h>
#define mybit LATBbits.LATB1 //LED
#define _XTAL_FREQ 10000000 //Using a crystal oscillator
void chk_isr(void);
void INT0_ISR(void);
void delay(unsigned int);
#pragma interrupt chk_isr //used for high-priority interrupt only
void chk_isr (void)
{
if(INTCONbits.INT0IF == 1) //INT0 causes interrupt?
INT0_ISR(); //Yes, Execute INT0ISR
}
#pragma code My_HiPrio_Int=0x08//high priority interrupt
void My_HiPrio_Int (void)
{
asm("GOTO chk_isr");
}
void main(void)
{
TRISBbits.TRISB1 = 0; //RB1 = output
mybit = 0; //Initially LED is OFF
TRISC = 0xFF; //PORTC = input
TRISD = 0; //PORTD = output
INTCONbits.INT0IF = 0; //clear INT0
INTCONbits.INT0IE = 1; //enable INT0 interrupt
INTCONbits.GIE = 1; //enable all interrupts globally
while(1)
{
PORTD = PORTC;
delay(500); //After 500 ms
INTCONbits.INT0IF = 1; //Flag
}
}
void INT0_ISR(void)
{
mybit=~mybit; //Toggle LED
INTCONbits.INT0IF = 0; //clear INT0 Flag
}
void delay(unsigned int delayInput) {
unsigned int mul = delayInput/50;
unsigned int count = 0;
for (count = 0; count <= mul; count ++)
__delay_ms(50);
}

Serial.Event() only runs once (using single char input)

On my Arduino Mega 2560, I'm trying to run a motor that turns a 20-vial container (accepting int input 1-20) while regulating temperature via PID of a separate cooler. I am generally new to this field of technology so bear with me. I also have an interrupt set up for an encoder to keep track of vial position.
The void serialEvent() and void loop() are the most important portions to look at, but I decided to put the rest of the code in there just in case you needed to see it.
#include <PID_v1.h>
#include <SPI.h>
#include <TMC26XStepper.h>
#define COOL_INPUT 0
#define PIN_OUTPUT 9
TMC26XStepper tmc26XStepper = TMC26XStepper(200,5,7,6,500);
int step = 6;
int value;
int i;
char junk = ' ';
volatile long enc_count = 0;
const byte interruptPinA = 2;
const byte interruptPinB = 3;
//Define Variables we'll be connecting to
int outMax = 255;
int outMin = -145;
double Setpoint, Input, Output;
double heatInput, heatOutput, originalInput;
//Specify the links and initial tuning parameters
// AGGRESSIVE VALUES (to get to 4 deg C)
double aggKp=8.0, aggKi=3.0, aggKd=0.15;
// CONSERVATIVE VALUES (to hover around 4 deg C)
double consKp=2.5, consKi = 0.0, consKd = 1.0;
PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd, REVERSE);
void setup()
{
pinMode(step, OUTPUT);
pinMode(interruptPinA, INPUT_PULLUP);
pinMode(interruptPinB, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPinA), encoder_isr, CHANGE);
attachInterrupt(digitalPinToInterrupt(interruptPinB), encoder_isr, CHANGE);
//initialize the variables we're linked to
Input = (5.0*analogRead(COOL_INPUT)*100.0) / 1024;
Setpoint = 10.75;
myPID.SetOutputLimits(outMin, outMax);
//turn the PID on
myPID.SetMode(AUTOMATIC);
Serial.begin(115200);
tmc26XStepper.setSpreadCycleChopper(2,24,8,6,0);
tmc26XStepper.setMicrosteps(32);
tmc26XStepper.setStallGuardThreshold(4,0);
Serial.println("...started...");
tmc26XStepper.start();
Serial.flush();
Serial.println("Enter vial numbers 1-20");
}
void loop() {
Input = (5.0*analogRead(COOL_INPUT)*100.0) / 1024;
// A BUNCH OF CODE FOR TEMP REGULATION
Serial.println(Input);
delay(150);
}
void serialEvent() {
while (Serial.available() == 0) {}
i = Serial.parseInt();
Serial.print("position: ");
Serial.print(i);
Serial.print(" ");
while (Serial.available() > 0) {
junk = Serial.read();
}
if (i == 1) {
value = 0;
} else {
int num = i - 1;
value = num * 72;
}
while (enc_count != value) {
digitalWrite(6, HIGH);
delayMicroseconds(100);
digitalWrite(6, LOW);
delayMicroseconds(100);
if (enc_count == 1440) {
enc_count = 0;
}
}
Serial.println(enc_count);
}
// INFO FOR ENCODER
void encoder_isr() {
static int8_t lookup_table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
static uint8_t enc_val = 0;
enc_val = enc_val << 2;
enc_val = enc_val | ((PIND & 0b1100) >> 2);
enc_count = enc_count + lookup_table[enc_val & 0b1111];
}
So, originally I had the two processes tested separately (vial position + encoder, then temperature regulation) and everything did exactly as it was supposed to. Now, I fused the code together and stored the vial position entry in the serialEvent() method to keep the temperature reading continuous and the vial position entry available for whenever I decided to provide input. However, when I put in a value, the program stops all together. I am able to see the number I entered (position: 5), but the Serial.println(enc_count) never gets printed. On top of the that, the temperature readings stop displaying readings.
Any thoughts? Need more information?

I'm looking for sample code to service the USCI (UART) on an MSP430 via DMA not interrupts

I have code that works "ok" for reading the USCI (UART) via interrupts, but the TI SimpliciTI stack is a CPU hog and it drops UART bytes when servicing the radio.
I assume DMA is the way to go, but I couldn't find a full example of DMA using USCI as input.
Here's what I ended up doing. It works!
struct {
#ifndef USE_DMA
volatile uint8_t rx_head ;
#endif
volatile uint8_t rx_tail ;
uint8_t rx_buffer[128];
} uart = { 0,0};
void UART_Init(void)
{
#ifndef USE_DMA
uart.rx_head = 0;
#endif
uart.rx_tail = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P1MAP5 = PM_UCA0RXD; // Map UCA0RXD output to P1.5
P1MAP6 = PM_UCA0TXD; // Map UCA0TXD output to P1.6
PMAPPWD = 0; // Lock port mapping registers
P1DIR |= BIT6; // Set P1.6 as TX output
P1SEL |= BIT5 + BIT6; // Select P1.5 & P1.6 to UART function
UCA0CTL1 = UCSWRST; // **Put state machine in reset**
#ifdef UART_9600
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_9600_SMCLK)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0xE2; // 12MHz/12500
UCA0BR1 = 0x04; //
UCA0MCTL = UCBRS_2+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_115200)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 104; // 12MHz/115200
UCA0BR1 = 0; //
UCA0MCTL = UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0
#else
#error Please select one of the supported baudrates.
#endif
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
#ifdef USE_DMA
memset(uart.rx_buffer,0,sizeof(uart.rx_buffer));
DMACTL0 = DMA0TSEL_16; // USCIA0 RX trigger
DMA0SAL = (uint16_t) &UCA0RXBUF; // Source address
DMA0DAL = (uint16_t) uart.rx_buffer; // Destination address
DMA0SZ = sizeof(uart.rx_buffer); // Block size. this counts down to 0, then reloads.
DMA0CTL = DMADSTINCR_3 + DMASBDB + DMADT_4 + DMALEVEL;
DMA0CTL |= DMAEN;
#else
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
#endif
}
int UART_GetChar(void)
{
#ifdef USE_DMA
if (DMA0SZ + uart.rx_tail != sizeof(uart.rx_buffer))
#else
if ( uart.rx_head != uart.rx_tail )
#endif
{
int c;
c = uart.rx_buffer[uart.rx_tail];
uint8_t next = uart.rx_tail + 1;
if (next >= sizeof(uart.rx_buffer)) next = 0;
uart.rx_tail = next;
return c;
}
return -1;
}

pic18f45550 usb problem

I am trying to build a very simple USB communication device using pic 18f4550
with default mikroelectronica example with no change (only change with hardware that I don't have couple of 100nf attached with vusb so I replaced them with 470uf
and I didn't put any pf with my crystal oscillator)
The hardware:
The code is working very will with Proteus simulation:
unsigned char k;
unsigned char userWR_buffer[64];
const char *text = "MIKROElektronika Compilers ER \r\n";
//**************************************************************************************************
// Main Interrupt Routine
//**************************************************************************************************
void interrupt()
{
HID_InterruptProc();
}
//**************************************************************************************************
//**************************************************************************************************
// Initialization Routine
//**************************************************************************************************
void Init_Main()
{
//--------------------------------------
// Disable all interrupts
//--------------------------------------
INTCON = 0; // Disable GIE, PEIE, TMR0IE,INT0IE,RBIE
INTCON2 = 0xF5;
INTCON3 = 0xC0;
RCON.IPEN = 0; // Disable Priority Levels on interrupts
PIE1 = 0;
PIE2 = 0;
PIR1 = 0;
PIR2 = 0;
ADCON1 |= 0x0F; // Configure all ports with analog function as digital
CMCON |= 7; // Disable comparators
//--------------------------------------
// Ports Configuration
//--------------------------------------
TRISA = 0xFF;
TRISB = 0xFF;
TRISC = 0xFF;
TRISD = 0;
TRISE = 0x07;
LATA = 0;
LATB = 0;
LATC = 0;
LATD = 0;
LATE = 0;
//--------------------------------------
// Clear user RAM
// Banks [00 .. 07] ( 8 x 256 = 2048 Bytes )
//--------------------------------------
}
//**************************************************************************************************
//**************************************************************************************************
// Main Program Routine
//**************************************************************************************************
void main() {
char i;
Init_Main();
HID_Enable(&userWR_buffer, &userWR_buffer);
Delay_ms(1000);
Delay_ms(1000);
while(1) {
Delay_ms(1000);
i=0;
while(text[i]) {
userWR_buffer[0]= text[i++];
while (!HID_Write(&userWR_buffer, 1));
}
}
Delay_ms(1000);
HID_Disable();
}
//**************************************************************************************************
I didn't put any pf with my crystal oscillator
I don't think this will work. Check with an oscilloscope what happens on your crystal. Your device has simply no clock input so it never executes anything.